package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.utils.StringUtils;
import com.xbongbong.coolapp.service.CoolAppCardService;
import com.xbongbong.crm.help.FineClueHelp;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.PaasProcessNodeTaskEntity;
import com.xbongbong.paas.domain.entity.PaasProcessTaskEntity;
import com.xbongbong.paas.domain.entity.PaasProcessTemplateEntity;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasAttachmentEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasCommentEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessNodeTaskEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateNodeEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.ProcessOpinionEnum;
import com.xbongbong.paas.enums.ProcessSearchStatusTodoEnum;
import com.xbongbong.paas.enums.ProcessTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.EsignHelp;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.UserInfoHelp;
import com.xbongbong.paas.help.analysis.data.FormDataListNoSubFormAnalysisDataHelp;
import com.xbongbong.paas.help.service.impl.FormDataLinkDataUpdateGetServiceImpl;
import com.xbongbong.paas.help.team.FormTeamSetHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.lowcode.CustomButtonService;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessNodeTaskModel;
import com.xbongbong.paas.model.PaasProcessRelatedDataModel;
import com.xbongbong.paas.model.PaasProcessTaskModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.model.PaasProcessTemplateNodeModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.pojo.ProcessNodeAllReadDTO;
import com.xbongbong.paas.pojo.ProcessNodeTaskLogPoJo;
import com.xbongbong.paas.pojo.ProcessNodeTaskOperatePojo;
import com.xbongbong.paas.pojo.ProcessNodeTaskPojo;
import com.xbongbong.paas.pojo.ProcessNodeTaskRecordsPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.CommentListDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.PaasBatchPrintByProcessDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeItemDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskCountDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskGetDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskListDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskReadDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskUpdateDTO;
import com.xbongbong.paas.pojo.dto.ProcessTaskDelDTO;
import com.xbongbong.paas.pojo.dto.SummaryDataDTO;
import com.xbongbong.paas.pojo.dto.UserGetDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.CommentListVO;
import com.xbongbong.paas.pojo.vo.LinkResultDataVO;
import com.xbongbong.paas.pojo.vo.PaasBatchPrintByProcessVO;
import com.xbongbong.paas.pojo.vo.PaasProcessNodeTaskVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.ProcessButtonVO;
import com.xbongbong.paas.pojo.vo.ProcessNextNodeTaskGetVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskCountVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskGet4IndexVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskGetVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskListVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskRecordsVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskShowVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskUpdateVO;
import com.xbongbong.paas.pojo.vo.ProcessOperateVo;
import com.xbongbong.paas.pojo.vo.ProcessTemplateNodeVO;
import com.xbongbong.paas.pojo.vo.SummaryDataVO;
import com.xbongbong.paas.pojo.vo.UserFormPermissionVO;
import com.xbongbong.paas.pojo.vo.UserGetVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.EsignService;
import com.xbongbong.paas.service.PaasCommentService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasProcessNodeTaskOperateService;
import com.xbongbong.paas.service.PaasProcessNodeTaskService;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.PaasDateUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataFormExplainHandleName;
import com.xbongbong.parent.parse.data.FormDataUpdateGetAnalysisDataHelp;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.PackageConstant;
import com.xbongbong.pro.coolapp.pojo.dto.CoolAppWorkflowCardDTO;
import com.xbongbong.pro.custombutton.pojo.dto.CustomButtonListDTO;
import com.xbongbong.pro.custombutton.pojo.vo.CustomButtonListVO;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.FundsSetErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.lowcode.ButtonTypeEnum;
import com.xbongbong.pro.enums.permission.enums.PrintProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormOwnerUniqueEnum;
import com.xbongbong.pro.enums.workrecord.enums.WorkrecordResultEnum;
import com.xbongbong.pro.esign.pojo.dto.EsignFlowStatusDTO;
import com.xbongbong.pro.esign.pojo.vo.EsignFlowStatusVO;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.label.pojo.LabelPojo;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.service.dingtalk.WorkflowDingtalkService;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.process.data.PaasProcessDataServiceImpl;
import com.xbongbong.process.ding.DingtalkWorkrecordService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.constant.PageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.PaymentConstant;
import com.xbongbong.saas.constant.StockConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.CouponEntity;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.EsignFlowStatusEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.SignTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.ManagementBaseEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CompetitorEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.ReturnEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.help.FormatProductHelp;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.InvoiceCommonHelper;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CouponModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.PublicGroupSeniorModel;
import com.xbongbong.saas.model.PurchaseInvoiceModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.ReturnService;
import com.xbongbong.saas.service.toolbox.help.FundMoneyHelp;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.SaasSaveHelper;
import com.xbongbong.saas.service.toolbox.help.UpdatePackageRedisService;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.ApproveUtil;
import com.xbongbong.util.ContractCompareUtil;
import com.xbongbong.util.ProcessUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: wufeng
 * @date: 2018/8/22 15:57
 * @desrcption:
 */
@Service(value = "paasProcessNodeTaskService")
public class PaasProcessNodeTaskServiceImpl implements PaasProcessNodeTaskService {

    private static final Logger LOG = LoggerFactory.getLogger(PaasProcessNodeTaskServiceImpl.class);

    @Resource
    private PaasProcessDataServiceImpl paasProcessDataService;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private PaasCommentService paasCommentService;
    @Resource
    private UserService userService;
    @Resource
    private PaasProcessNodeTaskOperateService paasProcessNodeTaskOperateService;
    @Resource
    private PaasProcessNodeTaskModel paasProcessNodeTaskModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasProcessTaskModel paasProcessTaskModel;
    @Resource
    private PaasProcessTemplateNodeModel processTemplateNodeModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private UserInfoHelp userInfoHelp;
    @Resource
    private FormDataUpdateGetAnalysisDataHelp formDataUpdateGetAnalysisDataHelp;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private SaasSaveHelper saasSaveHelper;
    @Resource
    private FormatProductHelp formatProductHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private FormDataLinkDataUpdateGetServiceImpl formDataLinkDataUpdateGetService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private LogHelp logHelp;
    @Resource
    private DingtalkWorkrecordService dingtalkWorkrecordService;
    @Resource
    private WorkflowDingtalkService workflowDingtalkService;
    @Resource
    private ProModelService proModelService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private FormDataFormExplainHandleName formDataFormExplainHandleName;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private FundMoneyHelp fundMoneyHelp;
    @Resource
    private InvoiceCommonHelper invoiceCommonHelper;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private EsignHelp esignHelp;
    @Resource
    private EsignService esignService;
    @Resource
    private PaasProcessRelatedDataModel paasProcessRelatedDataModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private PurchaseInvoiceModel purchaseInvoiceModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private CouponModel couponModel;
    @Resource
    private ReturnService returnService;
    @Resource
    private CustomButtonService customButtonService;
    @Resource
    private UpdatePackageRedisService updatePackageRedisService;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private RichTextService richTextService;
    @Resource
    private FineClueHelp fineClueHelp;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private FormTeamSetHelp formTeamSetHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private PublicGroupSeniorModel publicGroupSeniorModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private CoolAppCardService coolAppCardService;
    @Resource
    private FormDataListNoSubFormAnalysisDataHelp formDataListNoSubFormAnalysisDataHelp;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private ContractCompareUtil contractCompareUtil;
    @Resource
    private FormConfigModel formConfigModel;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ProcessNodeTaskUpdateVO update(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) throws XbbException {
        ProcessNodeTaskUpdateVO processNodeTaskUpdateVO;
        // 移除data里面的创建人和创建时间，这两个属性是放在data外面的
//        if (Objects.equals(processNodeTaskUpdateDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) && Objects.nonNull(processNodeTaskUpdateDTO.getDataList())) {
//            LOG.warn("processDataFromDingtalk" + JSON.toJSONString(processNodeTaskUpdateDTO.getDataList()));
//        }
        if (processNodeTaskUpdateDTO.getDataList() != null) {
            processNodeTaskUpdateDTO.getDataList().remove("creatorId");
            processNodeTaskUpdateDTO.getDataList().remove("addTime");
        }
        String hashKey = processNodeTaskUpdateDTO.getCorpid() + "_" + processNodeTaskUpdateDTO.getUserId() + "_" + processNodeTaskUpdateDTO.getProcessNodeTaskId();
        if (Objects.nonNull(paasRedisHelper.getValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey))) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_IS_DEAL);
        }
        try {
            String corpid = processNodeTaskUpdateDTO.getCorpid();
            Integer formNum = updatePackageRedisService.getUnusedNumPackageLimit(corpid, ValueAddedTypeEnum.CUSTOM_FORM_NUM);
            Integer appNum = updatePackageRedisService.getUnusedNumPackageLimit(corpid, ValueAddedTypeEnum.CUSTOM_FORM_NUM);
            if (Objects.equals(SaasMarkEnum.PAAS.getCode(), processNodeTaskUpdateDTO.getSaasMark())) {
                if (formNum > 0 || appNum > 0) {
                    if (appNum > 0) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(PackageConstant.FORM_PACKAGE_LIMIT_MESSAGE));
                    }
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(PackageConstant.CUSTOM_FORM_SIZE_MESSAGE), formNum));

                }
            }
            Long formId = processNodeTaskUpdateDTO.getFormId();
            // 当前审批类型 提交 暂存 拒绝 转交等
            Integer taskType = processNodeTaskUpdateDTO.getTaskType();
            TaskTypeEnum taskTypeEnum = TaskTypeEnum.getTaskTypeEnum(taskType);
            // 防止前端清空数据返回，不做任何操作
            if ((Objects.isNull(processNodeTaskUpdateDTO.getDataList()) || processNodeTaskUpdateDTO.getDataList().isEmpty()) &&
                    !Objects.equals(taskTypeEnum, TaskTypeEnum.REVOKE) && !Objects.equals(taskTypeEnum, TaskTypeEnum.END) && !Objects.equals(taskTypeEnum, TaskTypeEnum.BACK)) {
                return new ProcessNodeTaskUpdateVO();
            }
            paasRedisHelper.setValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey,true, RedisConstant.MICRO_DURATION);
            // 获取当前审批节点
            PaasProcessNodeTaskEntity entity = paasProcessNodeTaskModel.getByKey(processNodeTaskUpdateDTO.getProcessNodeTaskId().intValue(), processNodeTaskUpdateDTO.getCorpid());
            if (entity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            // 防止多次提交
            // 移动端两次撤回后重新提交会有bug，所以兼容处理。我提交的防重复点击失效
            if ((!Objects.equals(entity.getTaskType(), TaskTypeEnum.UNTREATED.getType()) && !Objects.equals(entity.getNodeType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType()))
                || Objects.equals(taskType, entity.getTaskType())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_HAVE_DEAL);
            }
            processNodeTaskUpdateDTO.setPaasProcessNodeTaskEntity(entity);

            // 查询任务所在当前节点模板信息
            PaasProcessTemplateNodeEntityExt processTemplateNodeEntity = processTemplateNodeModel.getByKey(entity.getTemplateNodeId().intValue(), processNodeTaskUpdateDTO.getCorpid());
            if (processTemplateNodeEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            PaasProcessTemplateEntity paasProcessTemplateEntity = paasProcessTemplateModel.getByKey(processTemplateNodeEntity.getTemplateId(), corpid);
            if (paasProcessTemplateEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TEMPLATE_NOT_EXIST);
            }
            processNodeTaskUpdateDTO.setProcessTemplateNode(processTemplateNodeEntity);

            // 获取之前的流程数据
            PaasProcessDataEntity processDataEntity = paasProcessDataModel.getByTaskId(processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getCorpid());
            if (Objects.isNull(processDataEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_DATA_NOT_EXIST);
            }
            Integer businessType = processNodeTaskUpdateDTO.getBusinessType();
            // 撤回,拒绝,回退不修改数据
            if (Objects.equals(taskTypeEnum, TaskTypeEnum.REVOKE)) {
                if (!Objects.equals(processDataEntity.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_HAVE_DEAL);
                }
                processNodeTaskUpdateDTO.setDataList(null);
                processNodeTaskUpdateDTO.setOwnerId(null);
                processNodeTaskUpdateDTO.setSaasNeedRedundantAttrPoJo(null);
                processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.revoke(processNodeTaskUpdateDTO);
                paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
                // 更新酷应用卡片
                updateCoolCard(processNodeTaskUpdateDTO);
                return processNodeTaskUpdateVO;
            } else if (Objects.equals(taskTypeEnum, TaskTypeEnum.END)) {
                processNodeTaskUpdateDTO.setDataList(null);
                processNodeTaskUpdateDTO.setOwnerId(null);
                processNodeTaskUpdateDTO.setSaasNeedRedundantAttrPoJo(null);
                PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = new PaasProcessNodeTaskEntity();
                BeanUtils.copyProperties(processNodeTaskUpdateDTO, paasProcessNodeTaskEntity);
                paasProcessNodeTaskEntity.setId(processNodeTaskUpdateDTO.getProcessNodeTaskId());
                // 审批图片，附件等
                if (processNodeTaskUpdateDTO.getImages() != null && !processNodeTaskUpdateDTO.getImages().isEmpty()) {
                    paasProcessNodeTaskEntity.setImages(JSONObject.toJSONString(processNodeTaskUpdateDTO.getImages()));
                }
                if (processNodeTaskUpdateDTO.getAttachmentList() != null && !processNodeTaskUpdateDTO.getAttachmentList().isEmpty()) {
                    paasProcessNodeTaskEntity.setAttachment(JSONObject.toJSONString(processNodeTaskUpdateDTO.getAttachmentList()));
                }
                paasProcessNodeTaskModel.update(paasProcessNodeTaskEntity);
                processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.end(processNodeTaskUpdateDTO);
                paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
                if (processNodeTaskUpdateDTO.getAtUserIds() != null && !processNodeTaskUpdateDTO.getAtUserIds().isEmpty()) {
                    paasCommentService.pushProcessComment(processNodeTaskUpdateDTO.getLoginUser(), processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getAtUserIds());
                }
                // 马雄说退货单审批拒绝还需要推送消息,还不能消息穿透
                if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
                    returnService.processTaskEnd(processNodeTaskUpdateDTO);
                }
                // 更新酷应用卡片
                updateCoolCard(processNodeTaskUpdateDTO);
                return processNodeTaskUpdateVO;
            } else if (Objects.equals(taskTypeEnum, TaskTypeEnum.BACK)){
                processNodeTaskUpdateDTO.setDataList(null);
                processNodeTaskUpdateDTO.setOwnerId(null);
                processNodeTaskUpdateDTO.setSaasNeedRedundantAttrPoJo(null);
                PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = new PaasProcessNodeTaskEntity();
                BeanUtils.copyProperties(processNodeTaskUpdateDTO, paasProcessNodeTaskEntity);
                paasProcessNodeTaskEntity.setId(processNodeTaskUpdateDTO.getProcessNodeTaskId());
                // 审批图片，附件等
                if (processNodeTaskUpdateDTO.getImages() != null && !processNodeTaskUpdateDTO.getImages().isEmpty()) {
                    paasProcessNodeTaskEntity.setImages(JSONObject.toJSONString(processNodeTaskUpdateDTO.getImages()));
                }
                if (processNodeTaskUpdateDTO.getAttachmentList() != null && !processNodeTaskUpdateDTO.getAttachmentList().isEmpty()) {
                    paasProcessNodeTaskEntity.setAttachment(JSONObject.toJSONString(processNodeTaskUpdateDTO.getAttachmentList()));
                }
                paasProcessNodeTaskModel.update(paasProcessNodeTaskEntity);
                processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.dingBack(processNodeTaskUpdateDTO);
                paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
                if (processNodeTaskUpdateDTO.getAtUserIds() != null && !processNodeTaskUpdateDTO.getAtUserIds().isEmpty()) {
                    paasCommentService.pushProcessComment(processNodeTaskUpdateDTO.getLoginUser(), processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getAtUserIds());
                }
                // 更新酷应用卡片
                updateCoolCard(processNodeTaskUpdateDTO);
                return processNodeTaskUpdateVO;
            } else if (Objects.equals(taskTypeEnum, TaskTypeEnum.COMMIT) || Objects.equals(taskTypeEnum, TaskTypeEnum.AGAIN_COMMIT)) {
                //重新提交时，回款单、销项发票、销售出库单需判断是否处于同一个模式，否则不能再次提交
                boolean sheetInvoiceOutstockFlag = Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
                if (sheetInvoiceOutstockFlag) {
                    Long modelType = processDataEntity.getSysLong10();
                    //获取当前处于什么模式
                    Long nowMmodelType = fundSetService.getModelType(corpid,XbbRefTypeEnum.CRM);
                    if (!Objects.equals(modelType, nowMmodelType)) {
                        String nowName = ModelTypeEnum.getNameByCode(nowMmodelType);
                        String modelName = ModelTypeEnum.getNameByCode(modelType);
                        throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248005, String.format(FundsSetErrorCodeEnum.API_ERROR_248005.getMsg(), modelName, nowName, taskTypeEnum.getStatusMemo()));
                    }
                }
            }
            // 查询解释
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            String formName = null;
            boolean isFree = false;
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
                WorkOrderFormEntityExt workOrderEntity = workOrderFormModel.getByKey(formId, corpid);
                if (workOrderEntity != null) {
                    formName = workOrderEntity.getName();
                }
                WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderEntity.getTemplateId(), corpid);
                isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                PaasFormEntityExt formEntity = paasFormModel.getByKey(formId, corpid);
                if (formEntity != null) {
                    formName = formEntity.getName();
                }
            }
            if (paasFormExplainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            processNodeTaskUpdateDTO.setDistributorMark(paasFormExplainEntity.getDistributorMark());
            List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            explainList.forEach(item->{
                Integer fieldType = item.getFieldType();
                if (Objects.equals(fieldType, FieldTypeEnum.LABEL.getType())){
                    JSONArray jsonArray = processNodeTaskUpdateDTO.getDataList().getJSONArray(item.getAttr());
                    JSONArray jsonArray1 = new JSONArray();
                    if (CollectionsUtil.isNotEmpty(jsonArray)) {
                        for (Object o : jsonArray) {
                            if ( o instanceof Map ) {
                                JSONObject jsonObject = (JSONObject)o;
                                jsonArray1.add(jsonObject.getLong("id"));
                            }
                        }
                        processNodeTaskUpdateDTO.getDataList().put(item.getAttr(),jsonArray1);
                    }
                }
            });
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) && !isFree) {
                explainMap.get(WorkOrderEnum.MANAGER_ID.getAttr()).setVisible(0);
            }

            boolean fieldPermission = (Objects.equals(1, paasProcessTemplateEntity.getUsePermission()) || !Objects.equals(processTemplateNodeEntity.getType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType())) && (Objects.equals(processDataEntity.getFormDataId(), 0L) || Objects.equals(processDataEntity.getSaasMark(), SaasMarkEnum.PAAS.getCode()));
            // 节点字段权限获取：1、新建进审批；2、如果是重新提交操作，需要判断开始节点是否了开启使用字段权限，其他节点则获取节点的字段权限
            if (fieldPermission) {
                // 不可见不校验必填 --start
                List<FieldPermissionEntityExt> fieldPermissionList = processTemplateNodeEntity.getFieldPermissionList();
                Map<String, FieldPermissionEntityExt> fieldPermissionMap = new HashMap<>(fieldPermissionList.size());
                fieldPermissionList.forEach((item)->{
                    String attr = item.getAttr();
                    if (StringUtil.isNotEmpty(item.getSubAttr())) {
                        attr = attr + StringConstant.POINT + item.getSubAttr();
                    }
                    fieldPermissionMap.put(attr, item);
                });

                ApproveUtil.setVisibleByFieldPermission(explainMap, fieldPermissionMap);
                // -- end
            }
            //格式可能是对象，code值在value内
            SheetTypeEnum sheetTypeEnum = fundHelp.getSheetTypeEnumByProcssData(businessType, processNodeTaskUpdateDTO.getDataList());
            //发票、回/付款单金额明细处理
            JSONArray amountDetail = saasSaveHelper.getAmountDetail4Check(processDataEntity.getFormDataId(), sheetTypeEnum, processNodeTaskUpdateDTO.getDataList(),businessType);

            //在此处就提前获取，防止在内部方法被置入了新的data
            JSONObject dataOld = JsonHelperUtil.parseObject(processDataEntity.getData());
            if (Objects.nonNull(processNodeTaskUpdateDTO.getOwnerId()) && !processNodeTaskUpdateDTO.getOwnerId().isEmpty()) {
                processDataEntity.setOwnerId(Objects.toString(processNodeTaskUpdateDTO.getOwnerId().get(0).getId(), ""));
            }
            // 数据格式校验
            ValidateDataDTO validateDataDTO = new ValidateDataDTO();
            //获取之前的数据
            JSONObject data = JSONObject.parseObject(processDataEntity.getData());
            if (Objects.nonNull(data.get("clueId"))) {
                processNodeTaskUpdateDTO.setClueId(data.getLong("clueId"));
            }
            if (Objects.nonNull(data.get("isBringCustomer"))) {
                processNodeTaskUpdateDTO.setIsBringCustomer(data.getInteger("isBringCustomer"));
            }
            Integer isOldProgressData = data.getInteger(StringConstant.IS_OLE_PROGRESS_DATA);
            processNodeTaskUpdateDTO.setIsOldProgressData(isOldProgressData);
            BeanUtil.copyProperties(processDataEntity, validateDataDTO);
            BeanUtil.copyProperties(processNodeTaskUpdateDTO, validateDataDTO);
            SaasNeedRedundantAttrPojo userfulSaasPojo = JSON.parseObject(processDataEntity.getSaasNeedPoJo(), SaasNeedRedundantAttrPojo.class);
            if (Objects.nonNull(userfulSaasPojo) && Objects.nonNull(validateDataDTO.getSaasNeedRedundantAttrPoJo())) {
                validateDataDTO.getSaasNeedRedundantAttrPoJo().setRefundId(userfulSaasPojo.getRefundId());
                validateDataDTO.getSaasNeedRedundantAttrPoJo().setReturnedPurchaseId(userfulSaasPojo.getReturnedPurchaseId());
            }
            validateDataDTO.setExplainMap(explainMap);
            validateDataDTO.setAmountDetail(amountDetail);
            if (!Objects.equals(processDataEntity.getFormDataId(), 0L)) {
                validateDataDTO.setDataId(processDataEntity.getFormDataId());
                processNodeTaskUpdateDTO.setFormDataId(processDataEntity.getFormDataId());
            }
            validateDataDTO.setData(processNodeTaskUpdateDTO.getDataList());
            ProSaveHelp.analyticalData(validateDataDTO);
            Set<Object> userIdList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if ( StringUtil.isNotEmpty(processDataEntity.getCreatorId())) {
                userIdList.add(processDataEntity.getCreatorId());
            }
            String creatorId = processDataEntity.getCreatorId();
            Boolean isCreateorIdExist = false;
            if ( StringUtil.isNotEmpty(creatorId) ) {
                UserEntity userEntity = userModel.getByKey(processDataEntity.getCreatorId(), corpid);
                if ( Objects.nonNull(userEntity) ) {
                    String userId = userEntity.getUserId();
                    if ( !isCreateorIdExist && Objects.equals(userId, creatorId) ) {
                        isCreateorIdExist = true;
                    }
                }
            }
            validateDataDTO.setTaskId(processNodeTaskUpdateDTO.getProcessTaskId());
            if ( !isCreateorIdExist ) {
                creatorId = null;
            }
            if (StringUtil.isNotEmpty(creatorId)) {
                // 在此处增加流程创建人权限获取等相关操作，避免在com.xbongbong.saas.service.toolbox.help.UserTeamHelp.specialBusinessHandle增加
               UserVO userVO = userService.getUserVO(corpid, creatorId, true, true);
               validateDataDTO.setLoginUser(userVO);
            }
            validateDataDTO.setCreatorId(creatorId);
            validateDataDTO.setProcessCreatorId(creatorId);
            validateDataDTO.setTaskTypeEnum(taskTypeEnum);
            setSpecialParam(processNodeTaskUpdateDTO, validateDataDTO);
            validateDataDTO.setFormDataId(processDataEntity.getFormDataId());
            validateDataDTO.setDataId(processDataEntity.getFormDataId());
            if (Objects.equals(paasFormExplainEntity.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())){
                validateDataDTO.setDistributorMark(paasFormExplainEntity.getDistributorMark());
            }
            formDataValidateDataHelp.validateData(validateDataDTO);
            // SaaS业务特殊处理
            if (Objects.equals(processNodeTaskUpdateDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                setOwnIdAndCoUserId(processNodeTaskUpdateDTO.getDataList(), validateDataDTO);
                JSONObject jsonObject = JsonHelperUtil.getJSONObject(processNodeTaskUpdateDTO.getDataList());
                // 资金上线前的合同审批中存在已收款的应收款，2020/1/12 时间戳比较
                if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) && Objects.nonNull(jsonObject.get(ContractEnum.ADD_PAYMENT.getAttr())) && processDataEntity.getAddTime() <= 1578758400) {
                    validateDataDTO.setIsOldProgressData(1);
                }
                if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode()) && Objects.nonNull(jsonObject.get(PurchaseEnum.ADD_PAYPLAN.getAttr())) && processDataEntity.getAddTime() <= 1590796800) {
                    validateDataDTO.setIsOldProgressData(1);
                }
                //审批中的isimport的值一直为空，考虑到这个地方目前不可能出现审批导入的情况，所以吧这个置为0
                validateDataDTO.setIsImport(0);
                saasSaveHelp.beforeSave(validateDataDTO);
            }else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), processNodeTaskUpdateDTO.getSaasMark())) {
                //现在paas业务也有更新团队的需求
                setOwnIdAndCoUserId(processNodeTaskUpdateDTO.getDataList(), validateDataDTO);
                saasSaveHelp.beforeSave(validateDataDTO);
            }
            processNodeTaskUpdateDTO.setSaasNeedRedundantAttrPoJo(validateDataDTO.getSaasNeedRedundantAttrPoJo());
            if (Objects.nonNull(validateDataDTO.getSaasNeedRedundantAttrPoJo())) {
                validateDataDTO.getSaasNeedRedundantAttrPoJo().setAmountDetail(amountDetail);
            }
            //退货退款ID传递
            if (dataOld.getLong(PaasConstant.REFUND_ID) != null) {
                validateDataDTO.getData().put(PaasConstant.REFUND_ID, dataOld.getLong(PaasConstant.REFUND_ID));
            }
            //采购退货单ID传递
            if (dataOld.getLong(PaasConstant.RETURNED_PURCHASE_ID) != null) {
                validateDataDTO.getData().put(PaasConstant.RETURNED_PURCHASE_ID, dataOld.getLong(PaasConstant.RETURNED_PURCHASE_ID));
            }
            if(Objects.equals(processNodeTaskUpdateDTO.getBusinessType(),XbbRefTypeEnum.COMPETITOR.getCode())){
                validateDataDTO.getData().put(CompetitorEnum.VISBLE_DEPT.getAttr(), validateDataDTO.getVisbleDept());
                validateDataDTO.getData().put(CompetitorEnum.VISBLE_USER.getAttr(), validateDataDTO.getVisbleUser());
            }

            processNodeTaskUpdateDTO.setDepartmentId(validateDataDTO.getDepartmentId());

            Integer opinionFlag = processTemplateNodeEntity.getOpinionFlag();
            String opinion = processNodeTaskUpdateDTO.getOpinion();
            // 审批意见必填时过滤暂存撤回操作
            if (Objects.equals(opinionFlag, ProcessOpinionEnum.REQUIRED.getValue()) && StringUtil.isEmpty(opinion, true)
                    && !Objects.equals(taskTypeEnum, TaskTypeEnum.STORAGE) && !Objects.equals(taskTypeEnum, TaskTypeEnum.REVOKE)
                    && !Objects.equals(taskTypeEnum, TaskTypeEnum.AGAIN_COMMIT) && !Objects.equals(taskTypeEnum, TaskTypeEnum.SYSTEM_COMMIT)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.APPROVE_OPINION_REQUIRED);
            }

            // 将审批意见等信息存储，更新当前任务的状态
            PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = new PaasProcessNodeTaskEntity();
            BeanUtils.copyProperties(processNodeTaskUpdateDTO, paasProcessNodeTaskEntity);
            paasProcessNodeTaskEntity.setId(processNodeTaskUpdateDTO.getProcessNodeTaskId());
            // 暂存时，不处理当前任务的状态
            if (!(Objects.equals(taskType, TaskTypeEnum.STORAGE.getType()) || Objects.equals(taskType, TaskTypeEnum.REVOKE.getType()))) {
                // 审批图片，附件等
                if (processNodeTaskUpdateDTO.getImages() != null && !processNodeTaskUpdateDTO.getImages().isEmpty()) {
                    paasProcessNodeTaskEntity.setImages(JSONObject.toJSONString(processNodeTaskUpdateDTO.getImages()));
                }
                if (processNodeTaskUpdateDTO.getAttachmentList() != null && !processNodeTaskUpdateDTO.getAttachmentList().isEmpty()) {
                    paasProcessNodeTaskEntity.setAttachment(JSONObject.toJSONString(processNodeTaskUpdateDTO.getAttachmentList()));
                }
                // 更新节点任务
                if (taskType.equals(TaskTypeEnum.AGAIN_COMMIT.getType())) {
                    paasProcessNodeTaskEntity.setIsRead(1);
                }
                paasProcessNodeTaskModel.update(paasProcessNodeTaskEntity);
                // 更新开始节点的已读未读状态
            }
            if (processNodeTaskUpdateDTO.getAtUserIds() != null && !processNodeTaskUpdateDTO.getAtUserIds().isEmpty()) {
                paasCommentService.pushProcessComment(processNodeTaskUpdateDTO.getLoginUser(), processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getAtUserIds());
            }
            // 流程操作
            processNodeTaskUpdateVO = dingOperateProcessNodeTask(taskTypeEnum, processNodeTaskUpdateDTO);
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);

            // 更新酷应用卡片
            updateCoolCard(processNodeTaskUpdateDTO);

            //处理完后再记录日志
            JSONObject dataNew = processNodeTaskUpdateDTO.getDataList();
            String userName = processNodeTaskUpdateDTO.getLoginUserName();
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_PROCESS_TASK), userName, formName);
            JSONObject oldObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(entity));
            JSONObject newObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(paasProcessNodeTaskEntity));
            //把数据更改也塞入进来（当表单数据变更时，需要处理）
            if (oldObj != null) {
                oldObj.put(StringConstant.JSON_DATA, dataOld);
            }
            if (newObj != null) {
                newObj.put(StringConstant.JSON_DATA, dataNew);
            }
            // 日志
            RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
            List<DetailLogPojo> detailArr = logHelp.getDetailArr4ProcessTaskAndData(corpid, redundantTemplateTypeEnum, explainMap, oldObj, newObj);
            mongoLogHelp.buildLog4DetailArr(detailArr, processNodeTaskUpdateDTO.getCorpid(), processNodeTaskUpdateDTO.getUserId(), userName,
                    OperateModuleTypeEnum.PAAS_PROCESS_TASK, OperateTypeEnum.EDIT, formId.toString(),
                    formName, memo, processNodeTaskUpdateDTO.getHttpHeader());
        } catch (XbbException e) {
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库流程操作出错", e);
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskUpdateVO;
    }

    /***
     * 更新酷应用卡片
     *
     * @param processNodeTaskUpdateDTO
     * @throws
     * @return void
     * @author hongxiao
     * @date 2022-07-05 14:43
     * @since
     * @version
     */
    private void updateCoolCard(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) {
        Runnable runnable = () -> {
            try {
                // 需要审批且群id不为空，调用酷应用方法
                CoolAppWorkflowCardDTO coolAppWorkflowCardDTO = new CoolAppWorkflowCardDTO(processNodeTaskUpdateDTO.getCorpid(), processNodeTaskUpdateDTO.getLoginUser(), PlatFormEnum.INTERNAL.getValue(),
                        null, processNodeTaskUpdateDTO.getAppId(), processNodeTaskUpdateDTO.getMenuId(), processNodeTaskUpdateDTO.getFormId(), processNodeTaskUpdateDTO.getSaasMark(),
                        processNodeTaskUpdateDTO.getBusinessType(), processNodeTaskUpdateDTO.getProcessTaskId(), null, processNodeTaskUpdateDTO.getFormDataId(), processNodeTaskUpdateDTO.getFlowStatus(), processNodeTaskUpdateDTO.getTaskType());
                if (TaskTypeEnum.AGAIN_COMMIT.getType().equals(processNodeTaskUpdateDTO.getTaskType())) {
                    coolAppWorkflowCardDTO.setPreTaskId(processNodeTaskUpdateDTO.getProcessTaskId());
                }
                coolAppCardService.updateProcessCard(coolAppWorkflowCardDTO);
            } catch (XbbException e) {
                // 不需要输出
            } catch (Exception e) {
                LOG.error("更新审批卡片失败", e);
            }
        };
        threadPoolBeanConfig.interactiveCardThreadPool().execute(runnable);
    }

    private void dealDingtalkParameter(ProcessNodeTaskGetDTO processNodeTaskGetDTO) {
        String userId = processNodeTaskGetDTO.getUserId();
        String corpid = processNodeTaskGetDTO.getCorpid();
        Long taskId = processNodeTaskGetDTO.getProcessTaskId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("userId", userId);
        params.put("corpid", corpid);
        params.put("del", 0);
        params.put("taskType", TaskTypeEnum.UNTREATED.getType());
        params.put("taskId", taskId);
        params.put("orderByStr", " id DESC ");
        List<PaasProcessNodeTaskEntityExt> paasProcessNodeTaskEntityExtList = paasProcessNodeTaskModel.findEntitys(params);
        if (!paasProcessNodeTaskEntityExtList.isEmpty()) {
            processNodeTaskGetDTO.setProcessType(ProcessTypeEnum.TODO.getValue());
            processNodeTaskGetDTO.setProcessNodeTaskId(paasProcessNodeTaskEntityExtList.get(0).getId());
        }
    }
    @Override
    public ProcessNodeTaskListVO allList(ProcessNodeTaskListDTO processNodeTaskListDTO) throws XbbException {
        ProcessNodeTaskListVO processNodeTaskListVO = new ProcessNodeTaskListVO();
        try {
            boolean pageSizeOverSize = Objects.nonNull(processNodeTaskListDTO.getPageSize()) && processNodeTaskListDTO.getPageSize() > 50;
            if (pageSizeOverSize) {
                // 审批分页条件大于50，则以"非法请求"处理
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "可能是非法请求");
            }
            if (!processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_APP.getAlias())
                || !processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS.getAlias())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAVE_NO_PERMISSION);
            }
            Map<String, Object> param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            Integer businessType = processNodeTaskListDTO.getBusinessType();
            getSaasBusinessType(processNodeTaskListDTO, param);

            getTimeRange(processNodeTaskListDTO, param);
            if (StringUtil.isNotEmpty(processNodeTaskListDTO.getCommitUserId())) {
                param.put("creatorId", processNodeTaskListDTO.getCommitUserId());
            }
            //审批编号搜索
            if(StringUtil.isNotEmpty(processNodeTaskListDTO.getSerialNoLike())){
                param.put("serialNoLike",processNodeTaskListDTO.getSerialNoLike());
            }
            param.put("orderByStr", " add_time desc");
            // 单据拆分兼容
            specialParams(param, businessType);
            PageHelper pageHelper = new PageHelper(processNodeTaskListDTO.getPage(), processNodeTaskListDTO.getPageSize());
            List<PaasProcessTaskEntity> taskList = (List<PaasProcessTaskEntity>) PageHelperUtil.getEntityList(param, pageHelper, paasProcessTaskModel);
            if (taskList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }
            if (isEmptyList(processNodeTaskListDTO, processNodeTaskListVO, taskList)) {
                return processNodeTaskListVO;
            }
            // 流程任务集合 processTaskMap
            List<Long> taskIdInList = new ArrayList<>();
            Map<Long, PaasProcessTaskEntity> processTaskMap = new HashMap<>(taskList.size());
            taskList.forEach((item) -> {
                taskIdInList.add(item.getId());
                processTaskMap.put(item.getId(), item);
            });
            // 最新流程节点任务集合 nodeTaskList
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            param.put("nodeTypeIn", Arrays.asList(NodeTypeEnum.START_PROCESS_NODE.getNodeType(), NodeTypeEnum.PROCESS_NODE.getNodeType()));
            param.put("taskTypeIn", Arrays.asList(TaskTypeEnum.UNTREATED.getType(), TaskTypeEnum.COMMIT.getType(), TaskTypeEnum.END.getType(), TaskTypeEnum.REVOKE.getType(), TaskTypeEnum.SYSTEM_COMMIT.getType()));
            param.put("orderByStr", " update_time " + SortOrder.DESC + ", id " + SortOrder.DESC);
            param.put("taskIdIn", taskIdInList);
            List<PaasProcessNodeTaskEntityExt> nodeTaskList = paasProcessNodeTaskModel.getLatestNodeForList(param);
            if (nodeTaskList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 模板节点集合 templateNodeMap
            List<Long> templateNodeIdInList = new ArrayList<>();
            nodeTaskList.forEach((item) -> templateNodeIdInList.add(item.getTemplateNodeId()));
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            param.put("idIn", templateNodeIdInList);
            param.remove("del");
            List<PaasProcessTemplateNodeEntityExt> templateNodeList = processTemplateNodeModel.list(param);
            if (templateNodeList == null || templateNodeList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            Map<Long, PaasProcessTemplateNodeEntityExt> templateNodeMap = new HashMap<>(templateNodeList.size());
            for (PaasProcessTemplateNodeEntityExt templateNode : templateNodeList) {
                templateNodeMap.put(templateNode.getId(), templateNode);
            }
            // 获取任务中摘要、任务、表单数据
            List<SummaryDataVO> summaryList = getSummaryList(processNodeTaskListDTO, templateNodeMap, processTaskMap, nodeTaskList);
            processNodeTaskListVO.setList(summaryList);
            processNodeTaskListVO.setPageHelper(pageHelper);
            processNodeTaskListVO.setProcessType(processNodeTaskListDTO.getProcessType());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask获取全部工作流列表出错,platForm:" + processNodeTaskListDTO.getPlatform(), e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskListVO;
    }

    private void getTimeRange(ProcessNodeTaskListDTO processNodeTaskListDTO, Map<String, Object> param) throws XbbException {
        if (processNodeTaskListDTO.getCommitTime().size() == BasicConstant.ONE) {
            List<Object> commitTime = PaasDateUtil.computeTime(processNodeTaskListDTO.getCommitTime());
            Long startTime = Long.valueOf(commitTime.get(0).toString());
            Long endTime = Long.valueOf(commitTime.get(1).toString());
            param.put("startTime", startTime);
            param.put("endTime", endTime);
        } else if (processNodeTaskListDTO.getCommitTime().size() == BasicConstant.TWO) {
            Long startTime = Long.valueOf(processNodeTaskListDTO.getCommitTime().get(0).toString());
            Long endTime = Long.valueOf(processNodeTaskListDTO.getCommitTime().get(1).toString());
            param.put("startTime", startTime / 1000);
            param.put("endTime", endTime / 1000);
            // 前端说时间筛选前端做兼容
            /*if (Objects.equals(startTime, endTime)) {
                param.put("endTime", endTime / 1000 + 86400);
            }*/
        }
    }

    @Override
    public ProcessNodeTaskGetVO detail(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskGetVO processNodeTaskGetVO = new ProcessNodeTaskGetVO();
        try {
            // 钉钉工作台特殊处理
            if (processNodeTaskGetDTO.getFromDingtalk()) {
                dealDingtalkParameter(processNodeTaskGetDTO);
            }
            processNodeTaskGetVO.setProcessType(processNodeTaskGetDTO.getProcessType());
            String corpid = processNodeTaskGetDTO.getCorpid();
            Long formId = processNodeTaskGetDTO.getFormId();
            String processType = processNodeTaskGetDTO.getProcessType();
            Integer businessType = processNodeTaskGetDTO.getBusinessType();
            Integer saasMark = processNodeTaskGetDTO.getSaasMark();
            Long taskId = processNodeTaskGetDTO.getProcessTaskId();
            // 检索流程表单数据
            PaasProcessDataEntity formData = paasProcessDataModel.getByTaskId(taskId, corpid);
            if (formData == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            Long addTime = formData.getAddTime();
            // 单据拆分前的出库单需要展示关联单据
            boolean needRefId = (Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode()) || Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_INSTOCK.getCode())) && Objects.nonNull(formData.getStockType());
            Long formDataId = formData.getFormDataId();
            String creatorId = formData.getCreatorId();
            if (!Objects.equals(0L, formDataId)) {
                PaasFormDataEntity paasFormDataEntity = proModelService.getFormDataEntity(corpid, saasMark, businessType, formDataId);
                if (Objects.nonNull(paasFormDataEntity)) {
                    creatorId = paasFormDataEntity.getCreatorId();
                }
            }
            JSONObject dataJsonObject = JSONObject.parseObject(formData.getData());
            processNodeTaskGetVO.setDataId(formDataId);
            //拼装富文本数据
            richTextService.addRichTextByTaskId(taskId, corpid, dataJsonObject);

            // 工单自由流程标识
            boolean isFree = false;
            // 获取表单实体
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formId, corpid);
                if (workOrderFormEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                //工单如果是自由流程，负责人字段显示并必填，指定流程不显示
                WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderFormEntity.getTemplateId(), corpid);
                isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
                paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                if (paasFormEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
            }
            Integer distributorMark = paasFormEntityExt.getDistributorMark();
            processNodeTaskGetVO.setDistributorMark(distributorMark);
            // 获取用户部门容器
            Map<String, Object> params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
            params.remove("del");
            params.put(ParameterConstant.LEAVE_MARKS,BasicConstant.ONE);
            List<UserEntity> userList = userModel.findEntitys(params);
            params.remove(ParameterConstant.LEAVE_MARKS);
            if (userList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            Map<String, UserEntity> userMap = new HashMap<>(userList.size());
            userList.forEach((item) -> userMap.put(item.getUserId(), item));
            params.remove(ParameterConstant.COLUMNS);
            // department不能用del条件，有del = 2的数据
            List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
            if (departmentList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
            }
            Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
            departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

            // 红冲回款，坏账用 防止dataJsonObject 防止转换过程中丢失
            JSONObject oldData = JSONObject.parseObject(formData.getData());
            // 获取表单解释
            PaasFormExplainEntity paasFormExplainEntity = getPaasFormExplain(corpid, formId, businessType, oldData, distributorMark);
            List<FieldAttrEntity> explainList = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

            // 获取当前流程主任务
            PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processNodeTaskGetDTO.getProcessTaskId().intValue(), corpid);
            if (paasProcessTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }

            if (Objects.equals(processNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                // 待处理的人员 移动端需要DING的人员id信息
                params.clear();
                params.put("corpid", corpid);
                params.put("taskId", taskId);
                params.put("taskType", TaskTypeEnum.UNTREATED.getType());
                params.put("del", 0);
                List<PaasProcessNodeTaskEntityExt> nodeTaskEntityExtList = paasProcessNodeTaskModel.findEntitys(params);
                List<String> unDealUserList = new ArrayList<>();
                nodeTaskEntityExtList.forEach(item -> unDealUserList.add(item.getUserId()));
                processNodeTaskGetVO.setUnDealUserList(unDealUserList);
            }

            // 获取节点数据
            PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = paasProcessNodeTaskModel.getByKey(processNodeTaskGetDTO.getProcessNodeTaskId().intValue(), corpid);
            if (paasProcessNodeTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            if (Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.ALL.getValue()) && Objects.equals(paasProcessNodeTaskEntity.getSignType(), SignTypeEnum.COUNTERSIGN.getValue())) {
                // 全部列表中，如果当前审批任务为会签时，获取没审批通过的任务
                params.clear();
                params.put("corpid", corpid);
                params.put("taskId", taskId);
                params.put("taskType", TaskTypeEnum.UNTREATED.getType());
                params.put("templateNodeId", paasProcessNodeTaskEntity.getTemplateNodeId());
                params.put("del", 0);
                List<PaasProcessNodeTaskEntityExt>  nodeList = paasProcessNodeTaskModel.findEntitys(params);
                if (CollectionUtils.isNotEmpty(nodeList)) {
                    // 获取一个未审批的节点任务，如果待审批的任务中审批人都离职了，以便于展示系统转交按钮
                    paasProcessNodeTaskEntity = nodeList.get(0);
                }
            }
            // 查询审批模板
            PaasProcessTemplateEntity processTemplate = paasProcessTemplateModel.getByKey(formData.getTemplateId(), corpid);
            if (processTemplate == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TEMPLATE_NOT_EXIST);
            }
            // 是否可以查看审批历史
            processNodeTaskGetVO.setAllowViewLog(processTemplate.getAllowViewLog());
            processNodeTaskGetVO.setVersionName(processTemplate.getVersionName());
            if (StringUtil.isEmpty(processTemplate.getVersionName())) {
                processNodeTaskGetVO.setVersionName("v1");
            }
            // 节点模板
            PaasProcessTemplateNodeEntityExt paasProcessTemplateNodeEntityExt = processTemplateNodeModel.getByKey(paasProcessNodeTaskEntity.getTemplateNodeId().intValue(), corpid);
            if (paasProcessTemplateNodeEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }

            // 为了产品内的成本高级权限走一遍表单权限format
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            handlerExplainDTO.setOwnerId(Collections.singletonList(formData.getOwnerId()));
            handlerExplainDTO.setCreatorId(creatorId);
            BeanUtil.copyProperties(processNodeTaskGetDTO, handlerExplainDTO, false);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);
            handlerExplainDTO.setFormData(dataJsonObject);
            HandlerExplainVO handlerExplainVO = formDataFormExplainHandleName.handleExplain(handlerExplainDTO);
            if (handlerExplainVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            explainList = handlerExplainVO.getHeadList();

            // 解析数据信息
            // 存入系统字段到data中
            dataJsonObject.put(FieldTypeEnum.SERIALNO.getAlias(), formData.getSerialNo());
            if (formData.getDepartmentId() != null && !Objects.equals(formData.getDepartmentId(), 0L)) {
                dataJsonObject.put(FieldTypeEnum.DEPARTMENTID.getAlias(), formData.getDepartmentId());
            }
            // 解析新版协同人和负责人
            JSONArray ownIdList = dataJsonObject.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
            JSONArray coUserIdList = dataJsonObject.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
            //这边需要兼容一下团队成员上线之后一些老数据兼容处理
            handTeamOldProcessData(ownIdList, coUserIdList, dataJsonObject, businessType, corpid, addTime);
            if (CollectionsUtil.isNotEmpty(ownIdList)) {
                List<ReturnUserAndDepartmentPojo> ownList = new ArrayList<>();
                for (Object o : ownIdList) {
                    String id;
                    if (o instanceof JSONObject) {
                        id = ((JSONObject) o).getString(StringConstant.SAAS_LINK_BUSINESS_ID);
                    } else {
                        id = o.toString();
                    }
                    UserEntity user = userMap.get(id);
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    if (Objects.nonNull(user)) {
                        BeanUtil.copyProperties(user, returnUserAndDepartmentPojo);
                        returnUserAndDepartmentPojo.setId(user.getUserId());
                        ownList.add(returnUserAndDepartmentPojo);
                    }
                }
                dataJsonObject.put(FieldTypeEnum.OWNERID.getAlias(), ownList);
            }
            if (CollectionsUtil.isNotEmpty(coUserIdList)) {
                List<ReturnUserAndDepartmentPojo> coUserList = new ArrayList<>();
                for (Object o : coUserIdList) {
                    String id;
                    if (o instanceof JSONObject) {
                        id = ((JSONObject) o).getString(StringConstant.SAAS_LINK_BUSINESS_ID);
                    } else {
                        id = o.toString();
                    }
                    UserEntity user = userMap.get(id);
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    if (Objects.nonNull(user)) {
                        BeanUtil.copyProperties(user, returnUserAndDepartmentPojo);
                        returnUserAndDepartmentPojo.setId(user.getUserId());
                        coUserList.add(returnUserAndDepartmentPojo);
                    }
                }
                dataJsonObject.put(FieldTypeEnum.COUSERID.getAlias(), coUserList);
            }
            // 字段权限
            List<FieldPermissionEntityExt> fieldPermissionEntityList = paasProcessTemplateNodeEntityExt.getFieldPermissionList();
            //2020/6/10 28311 紧急封掉撤销审批后可以编辑关联字段, 之后重构发票之后可以去除掉这边的发票特殊逻辑
            boolean inpurtInvoiceFlag = Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode());
            // 是SaaS的业务并且formDataId不等于0并且不是后置进审批
            boolean isSaasEdit = Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) && !Objects.equals(formDataId, 0L) && !Objects.equals(formData.getPostPosition(), 1);
            if (fieldPermissionEntityList != null && !fieldPermissionEntityList.isEmpty()) {
                // 解释格式format
                FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, formatExplainDTO);
                formatExplainDTO.setExplainList(explainList);
                PaasFormDataEntityExt paasFormData = new PaasFormDataEntityExt();
                paasFormData.setData(JSONObject.parseObject(formData.getData()));
                BeanUtil.copyProperties(formData, paasFormData);
                formatExplainDTO.setDataEntity(paasFormData);
                formatExplainDTO.setResult(dataJsonObject);
                if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                    formatExplainDTO.setFromCopy(!isSaasEdit);
                    formExplainHelp.formatExplain(formatExplainDTO, null);
                    processNodeTaskGetVO.setSaasSpecialParamPojo(formatExplainDTO.getSaasSpecialParamPojo());
                    // 解释中数据字典值
                    List<ItemPoJo> items = new ArrayList<>();
                    for (FieldAttrEntity fieldAttrEntity : explainList) {
                        if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())) {
                            items = fieldAttrEntity.getItems();
                        }
                    }
                    explainList = paasFormExplainService.handleExplainList(explainList, businessType, corpid, formId);
                    for (FieldAttrEntity fieldAttrEntity : explainList) {
                        if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())) {
                            items = items.stream().filter(item -> Objects.equals(item.getEnable(), 1)).collect(Collectors.toList());
                            fieldAttrEntity.setItems(items);
                        }
                    }
                }
                // 根据节点权限设置编辑权限 saas数据编辑进审批不读权限
                List<FieldAttrEntity> headList;
                if (!isSaasEdit) {
                    boolean isStartNode = Objects.equals(paasProcessTemplateNodeEntityExt.getType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType());
                    if (Objects.equals(processTemplate.getUsePermission(), 1) || !isStartNode) {
                        headList = ExplainUtil.parseExplainListByFieldPermission(explainList, fieldPermissionEntityList, isStartNode, businessType, processNodeTaskGetDTO.getLoginUser());
                    } else {
                        // 使用表单权限
                        headList = explainList;
                        for (FieldAttrEntity entity: explainList) {
                            if (ExplainUtil.invisibleOfScope(entity, handlerExplainDTO)) {
                                entity.setVisible(0);
                            }
                        }
                    }
                } else {
                    // 异或的解释处理
                    headList = xorExplainListByFieldPermission(explainList, fieldPermissionEntityList, processNodeTaskGetDTO.getLoginUser());
                }

                // 审批完成后不允许编辑 节点数据不是未处理和撤回状态
                boolean disable = (Objects.equals(processType, ProcessTypeEnum.TODO.getValue()) && !Objects.equals(paasProcessNodeTaskEntity.getTaskType(), TaskTypeEnum.UNTREATED.getType()))
                        || (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue()) && !(Objects.equals(paasProcessTaskEntity.getFlowStatus(), FlowStatusEnum.REVOKE.getType())
                        || Objects.equals(paasProcessTaskEntity.getFlowStatus(), FlowStatusEnum.REJECT.getType())))
                        || (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue()) && !Objects.equals(formDataId, 0L))
                        || Objects.equals(processType, ProcessTypeEnum.CC.getValue()) || processType.equals(ProcessTypeEnum.ALL.getValue());
                List<String> featureList = packageHelp.getFeatureList(corpid);
                boolean formShareTag = userTeamHelp.getFormShareTag(corpid, formId, businessType);

                Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
                boolean ultimateTag = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
                for (FieldAttrEntity fieldAttrEntity : headList) {
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    // 工单需要根据模板判断负责人显不显示
                    if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                        if (!isFree) {
                            //指定流程。设置负责人不可见
                            if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.USER.getType())
                                    && Objects.equals(WorkOrderEnum.MANAGER_ID.getAttr(), fieldAttrEntity.getAttr())) {
                                fieldAttrEntity.setVisible(0);
                                fieldAttrEntity.setEditable(0);
                            }
                        } else {
                            if (fieldType != null && Objects.equals(fieldAttrEntity.getAttr(),WorkOrderEnum.MANAGER_ID.getAttr())) {
                                fieldAttrEntity.setEditable(0);
//                                UserEntity userEntity = userMap.get(dataJsonObject.getString(fieldAttrEntity.getAttr()));
//                                if (userEntity != null) {
//                                    ReturnUserAndDepartmentPojo returnUserPojo = new ReturnUserAndDepartmentPojo();
//                                    BeanUtil.copyProperties(userEntity, returnUserPojo);
//                                    returnUserPojo.setId(userEntity.getUserId());
//                                    dataJsonObject.put(fieldAttrEntity.getAttr(), returnUserPojo);
//                                }
                            }
                        }
                    } else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), OutstockEnum.TYPE.getAttr())) {
                        fieldAttrEntity.getItems().forEach(itemPoJo -> itemPoJo.setFieldMap(null));
                    } else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), OutstockEnum.REF_ID.getAttr()) && Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
                        fieldAttrEntity.setEditable(0);
                    } else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), InstockEnum.REF_ID.getAttr()) && Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                        fieldAttrEntity.setEditable(0);
                    } else if (Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType()) && Objects.equals(businessType, XbbRefTypeEnum.SUPPLIER.getCode())) {
                        fieldAttrEntity.setVisible(0);
                    }
                    // 字段回收站处理
                    if (Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                        fieldAttrEntity.setVisible(0);
                    }
                    if (disable) {
                        fieldAttrEntity.setEditable(0);
                        if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType()) || Objects.equals(fieldType, FieldTypeEnum.SINGLE_SUB_FORM.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.CONTACT_NUMBER.getType()) || Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType())) {
                            List<? extends FieldAttrEntity> subList = fieldAttrEntity.getSubForm().getItems();
                            for (FieldAttrEntity subAttr : subList) {
                                subAttr.setEditable(0);
                                // 字段回收站处理
                                if (Objects.equals(subAttr.getIsOpen(), 2)) {
                                    subAttr.setVisible(0);
                                }
                            }
                            fieldAttrEntity.getSubForm().setItems(subList);
                        }

                    }
                    // 设置创建人和创建时间的showType为0
                    if ((Objects.equals(fieldType, FieldTypeEnum.CREATORID.getType()) && !Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()))
                        || Objects.equals(fieldType, FieldTypeEnum.ADDTIME.getType())) {
                        fieldAttrEntity.setShowType(ShowTypeEnum.ALL.getCode());
                        fieldAttrEntity.setEditable(0);
                    }
                    if (ExplainUtil.isSubForm(fieldType)) {
                        if (Objects.nonNull(fieldAttrEntity.getSubForm()) && Objects.nonNull(fieldAttrEntity.getSubForm().getItems())) {
                            List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                            subFieldList.forEach(item->{
                                // 套餐逻辑，标准版本隐藏复杂字段
                                packageHelp.explainHide(featureList, item);
                                // 套餐逻辑，数据联动和联动其他表单
                                packageHelp.setPackageLimit(featureList, item);
                                // 限制公式
                                packageHelp.limitFormula(featureList, item, businessType);
                            });
                        }
                    } else {
                        // 套餐逻辑，标准版本隐藏复杂字段
                        packageHelp.explainHide(featureList, fieldAttrEntity);
                        // 套餐逻辑，数据联动和联动其他表单
                        packageHelp.setPackageLimit(featureList, fieldAttrEntity);
                        // 限制公式
                        packageHelp.limitFormula(featureList, fieldAttrEntity, businessType);
                    }
                    //隔离模式下工作流团队字段权限处理 ：只展示团队负责人，负责人不可编辑
                    if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType)) {
                        if(!formShareTag){
                            if(Objects.equals(FieldTypeEnum.OWNERID.getAlias(),fieldAttrEntity.getAttr())){
                                fieldAttrEntity.setVisible(Constant.ONE);
                                fieldAttrEntity.setEditable(Constant.ZERO);
                            }
                            if(Objects.equals(FieldTypeEnum.COUSERID.getAlias(),fieldAttrEntity.getAttr())){
                                fieldAttrEntity.setVisible(Constant.ZERO);
                            }
                        }
                    }
                    //根据套餐设置负责人字段属性
                    if(Objects.equals(fieldAttrEntity.getAttr(),FieldTypeEnum.OWNERID.getAlias())){
                        if(!ultimateTag && FormOwnerUniqueEnum.getDefaultBusinessList().contains(businessType)) {
                            //只有旗舰版支持负责人唯一设置，其他版本拿默认设置
                            FormOwnerUniqueEnum formOwnerUniqueEnum = FormOwnerUniqueEnum.getFormOwnerUniqueByBus(businessType);
                            Integer multiple = formOwnerUniqueEnum.getValue();
                            fieldAttrEntity.setMultiple(multiple);
                        }
                    }

                }
                SheetTypeEnum sheetTypeEnum = fundHelp.getSheetTypeEnumByProcssData(businessType, dataJsonObject);
                boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
                if (sheetFlag) {
                    boolean isNew = Objects.isNull(formDataId) || Objects.equals(formDataId, 0L);
                    //如果是回/付款单、其他收入/支出单，则根据数据data内的回/付款单/其他收入/支出单类型重置sheetTypeEnum（前端传过来的businessType可能没有详细区分哪种类型回/付款单/其他收入/支出单）
                    fundHelp.handlePaymentSheet(isNew, sheetTypeEnum, headList, corpid, distributorMark);
                    fundHelp.setBySheetType(paasFormEntityExt, sheetTypeEnum);
                }
                if(inpurtInvoiceFlag){
                    //暂时封住
                    fundHelp.handleInvoice(headList);
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                    //处理账期
                    fundSetService.formatPeriod(corpid, businessType, formId, explainList);
                }
                processNodeTaskGetVO.setHeadList(headList);
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_PERMISSION_NOT_EXIST);
            }
            // SaaS特殊处理
            specialDealForSaas(businessType, dataJsonObject, explainList);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>(processNodeTaskGetVO.getHeadList().size());
            for (FieldAttrEntity item : processNodeTaskGetVO.getHeadList()) {
                explainMap.put(item.getAttr(), item);
                // 去掉关联新建的数据
                // if (Objects.equals(item.getFieldType(), FieldTypeEnum.LINK_FORM.getType())) {
                //     dataJsonObject.remove(item.getAttr());
                // }
            }

            // saas业务数据格式转换 调用编辑的回显format
            if (Objects.equals(paasProcessTaskEntity.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, saasAnalysisDataDTO);
                BeanUtil.copyProperties(paasProcessTaskEntity, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setUserId(processNodeTaskGetDTO.getUserId());
                saasAnalysisDataDTO.setForProcess(true);
                if (Objects.equals(distributorMark,DistributorMarkEnum.DISTRIBUTOR.getCode())){
                    saasAnalysisDataDTO.setDistributorMark(distributorMark);
                }
                saasUpdateHelp.formatData(saasAnalysisDataDTO, dataJsonObject);
                if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                    dataJsonObject.putIfAbsent(InventoryEnum.INVENTORY_TYPE.getAttr(), 2);
                }
                formatProductHelp.formatProduct(saasAnalysisDataDTO, dataJsonObject, explainList, false);
            }
            // 解析数据信息
            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
            BeanUtil.copyProperties(processNodeTaskGetDTO, parseSingleRowDataDTO);
            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
            parseSingleRowDataDTO.setUserMap(userMap);
            parseSingleRowDataDTO.setExplainMap(explainMap);
            parseSingleRowDataDTO.setDataJsonObject(dataJsonObject);
            parseSingleRowDataDTO.setIsProcess(true);
            ParseSingleRowDataVO parseSingleRowDataVO = formDataUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
            if (parseSingleRowDataVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
            }
            dataJsonObject = parseSingleRowDataVO.getResult();

            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode()) ) {
                String publicGroup = FastJsonHelper.getStringFromFormData(dataJsonObject, CustomerManagementEnum.PUBLIC_GROUP.getAttr());
                if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    publicGroup = FastJsonHelper.getStringFromFormData(dataJsonObject, ClueEnum.PUBLIC_GROUP.getAttr());
                }
                if(StringUtil.isNotEmpty(publicGroup)){
                    PublicGroupSeniorEntity publicGroupSeniorEntity = publicGroupSeniorModel.getByKey(Long.valueOf(publicGroup), corpid);
                    if (Objects.nonNull(publicGroupSeniorEntity)) {
                        dataJsonObject.put(CustomerManagementEnum.PUBLIC_GROUP.getAttr(), publicGroupSeniorEntity.getName());
                    }
                }
            }
            // 关联查询
            LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
            // 获取关联数据的信息
            if (linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty()) {
                linkResultDataVO.setData(dataJsonObject);
                linkResultDataVO.setExplainMap(explainMap);
                linkResultDataVO.setExplainList(explainList);
                linkResultDataVO.setUserMap(userMap);
                linkResultDataVO.setDepartmentMap(departmentMap);
                FormDataUpdateGetDTO formDataUpdateDTO = new FormDataUpdateGetDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, formDataUpdateDTO);
                dataJsonObject = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataUpdateDTO, linkResultDataVO);
            }
            //只有发票、回/付款单才有明细，其他收入、其他支出无明细
            boolean sheetFlag = Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode());
            boolean invoiceFlag = Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            if (sheetFlag || invoiceFlag) {
                SaasNeedRedundantAttrPojo saasNeedPojo = JSONObject.parseObject(formData.getSaasNeedPoJo(), SaasNeedRedundantAttrPojo.class);
                JSONArray amountDetail = Objects.nonNull(saasNeedPojo) ? saasNeedPojo.getAmountDetail() : null;
                //二期不用去数据库取金额明晰直接 调用方法自动生成范围 三期改造销项发票时可以直接用这种方法
                if(Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    amountDetail = purchaseInvoiceModel.approveGetAmountDetail(corpid,businessType, JSONObject.parseObject(formData.getData()), formData.getFormDataId(), formData.getSaasNeedPoJo());
                }
                if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                    amountDetail = invoiceModel.approveGetSalesAmountDetail(corpid,businessType, JSONObject.parseObject(formData.getData()), formData.getFormDataId(), formData.getSaasNeedPoJo());
                }
                if (sheetFlag && Objects.isNull(amountDetail)) {
                    JSONObject data = JSONObject.parseObject(formData.getData());
                    //回/付款单，没有明细则渲染一个默认的明细（把父单的data信息塞入明细即可）
                    amountDetail = fundHelp.getDefaultAmountDetail(data, null);
                }
                dataJsonObject.put(PaasConstant.AMOUNTDETAIL, amountDetail);
                if(invoiceFlag){
                    String originIdAttr = "";
                    if(Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())){
                        originIdAttr = InvoiceEnum.ORIGIN_ID.getAttr();
                    }else if(Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                        originIdAttr = PurchaseInvoiceEnum.ORIGIN_ID.getAttr();
                    }
                    if(dataJsonObject.containsKey(originIdAttr)){
                        JSONArray originArray = null;
                        if(Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())){
                            originArray = dataJsonObject.getJSONArray(InvoiceEnum.ORIGIN_ID.getAttr());
                        }else if(Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                            originArray = dataJsonObject.getJSONArray(PurchaseInvoiceEnum.ORIGIN_ID.getAttr());
                        }
                        JSONObject originJson = null;
                        if(CollectionsUtil.isNotEmpty(originArray)){
                            originJson = originArray.getJSONObject(0);
                        }

                        SaasSpecialParamPojo saasSpecialParamPojo = processNodeTaskGetVO.getSaasSpecialParamPojo();
                        if(Objects.isNull(processNodeTaskGetVO.getSaasSpecialParamPojo())){
                           saasSpecialParamPojo = new SaasSpecialParamPojo();
                        }
                        if(Objects.nonNull(originJson)) {
                            if (originJson.getLong(BasicConstant.ID) > BasicConstant.ZERO) {
                                saasSpecialParamPojo.setFromRed(BasicConstant.ONE);
                                processNodeTaskGetVO.setSaasSpecialParamPojo(saasSpecialParamPojo);
                                if(CollectionsUtil.isNotEmpty(processNodeTaskGetVO.getHeadList())){
                                    for(FieldAttrEntity fieldAttrEntity : processNodeTaskGetVO.getHeadList()){
                                        if(Objects.equals(fieldAttrEntity.getSaasAttr(), InvoiceEnum.TOTAL_MONEY.getSaasAttr())){
                                            fieldAttrEntity.setAttrName(InvoiceConstant.REDSTRING+fieldAttrEntity.getAttrName());
                                        }
                                    }
                                }
                                if(Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode()) || Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                                    invoiceCommonHelper.getMinusAmountFormRedInvoice(dataJsonObject,amountDetail,originJson.getLong(BasicConstant.ID),BasicConstant.ZERO,businessType);
                                }
                            } else {
                                saasSpecialParamPojo.setFromRed(BasicConstant.ZERO);
                                processNodeTaskGetVO.setSaasSpecialParamPojo(saasSpecialParamPojo);
                            }
                        }
                    }
                    if(Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())){
                        fundMoneyHelp.setPrePaymentSheetType(dataJsonObject,corpid);
                    }else if(Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                        fundMoneyHelp.setPrePaySheetType(dataJsonObject,corpid);
                    }
                }
            }
            // node任务的vo对象
            PaasProcessNodeTaskVO paasProcessNodeTaskVO = new PaasProcessNodeTaskVO();
            BeanUtil.copyProperties(paasProcessNodeTaskEntity, paasProcessNodeTaskVO);
            paasProcessNodeTaskVO.setSaasMark(paasProcessTaskEntity.getSaasMark());
            paasProcessNodeTaskVO.setOpinionFlag(paasProcessTemplateNodeEntityExt.getOpinionFlag());
            paasProcessNodeTaskVO.setBusinessType(paasProcessTaskEntity.getBusinessType());

            UserEntity commitUserEntity = userMap.get(paasProcessTaskEntity.getCreatorId());
            UserEntity creator = userMap.get(creatorId);
            if (Objects.nonNull(creator)) {
                UserVO creatorUser = new UserVO();
                BeanUtil.copyProperties(creator, creatorUser);
                paasProcessNodeTaskVO.setCreatorUser(creatorUser);
                // 创建人数据
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", creator.getUserId());
                jsonObject.put("name", creator.getName());
                jsonObject.put("avatar", creator.getAvatar());
                dataJsonObject.put(FieldTypeEnum.CREATORID.getAlias(), jsonObject);
            }
            if (Objects.nonNull(commitUserEntity)) {
                UserVO commitUser = new UserVO();
                BeanUtil.copyProperties(commitUserEntity, commitUser);
                processNodeTaskGetVO.setCommitUser(commitUser);
                if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                    paasFormEntityExt.setName(XbbRefTypeEnum.INVOICE.getName());
                }
                processNodeTaskGetVO.setTitle(commitUserEntity.getName().replace("(离职)","") + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));

            } else {
                // 人员离职
                processNodeTaskGetVO.setTitle("***" + I18nMessageUtil.getMessage(CommonConstant.OF)  + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));
                UserVO commitUser = new UserVO();
                BeanUtil.copyProperties(processNodeTaskGetDTO.getLoginUser(), commitUser);
                commitUser.setName("***(" + I18nMessageUtil.getMessage(I18nStringConstant.RESIGNED)+ ")");
                commitUser.setUserId("0");
                processNodeTaskGetVO.setCommitUser(commitUser);
                paasProcessNodeTaskVO.setCreatorUser(commitUser);
            }

            // 转交和撤回人
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getTransferUserId()) && userMap.containsKey(paasProcessNodeTaskVO.getTransferUserId())) {
                UserVO userVO = new UserVO();
                BeanUtil.copyProperties(userMap.get(paasProcessNodeTaskVO.getTransferUserId()), userVO);
                paasProcessNodeTaskVO.setTransferUser(userVO);

            }
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getRevokeUserId()) && userMap.containsKey(paasProcessNodeTaskVO.getRevokeUserId())) {
                UserVO userVO = new UserVO();
                BeanUtil.copyProperties(userMap.get(paasProcessNodeTaskVO.getRevokeUserId()), userVO);
                paasProcessNodeTaskVO.setRevokeUser(userVO);
            }

            // 节点任务中文描述
            paasProcessNodeTaskVO.setTaskTypeMemo(TaskTypeEnum.getStatusMemo(paasProcessNodeTaskVO.getTaskType()));
            TaskTypeEnum taskTypeEnum = TaskTypeEnum.getTaskTypeEnum(paasProcessNodeTaskVO.getTaskType());
            if (taskTypeEnum != null) {
                paasProcessNodeTaskVO.setColor(taskTypeEnum.getColor());
            }
            if ( Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType,XbbRefTypeEnum.PURCHASE.getCode())) {
                boolean isNew = Objects.equals(formDataId, 0L) || Objects.isNull(formDataId);
                Double writeOffAmount = 0D;
                if ( !isNew ) {
                    FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
                    BeanUtil.copyProperties(processNodeTaskGetDTO, formDataUpdateGetDTO);
                    formDataUpdateGetDTO.setDataId(formDataId);
                    writeOffAmount = fundMoneyHelp.getCoverCalAmount(formDataUpdateGetDTO,explainMap,businessType);
                }
                processNodeTaskGetVO.setWriteOffAmount(writeOffAmount);
            }
            // 创建时间
            dataJsonObject.put(FieldTypeEnum.ADDTIME.getAlias(), formData.getAddTime());
            // saas特殊处理
            saasSpecialHandle(paasProcessNodeTaskVO, dataJsonObject, processNodeTaskGetVO, businessType);
            paasProcessNodeTaskVO.setFieldPosition(paasFormEntityExt.getFieldPosition());
            processNodeTaskGetVO.setProcessNodeTask(paasProcessNodeTaskVO);
            processNodeTaskGetVO.setName(paasFormEntityExt.getName());
            processNodeTaskGetVO.setData(dataJsonObject);
            processNodeTaskGetVO.setSerialNo(formData.getSerialNo());
            // 提交给我和抄送给我的用节点状态
            if (Objects.equals(ProcessTypeEnum.TODO.getValue(), processType) || Objects.equals(ProcessTypeEnum.CC.getValue(), processType)) {
                processNodeTaskGetVO.setFlowStatus(paasProcessNodeTaskEntity.getTaskType());
                processNodeTaskGetVO.setFlowStatusDesc(ProcessSearchStatusTodoEnum.getStatusMemo(paasProcessNodeTaskEntity.getTaskType()));
            } else {
                processNodeTaskGetVO.setFlowStatus(paasProcessTaskEntity.getFlowStatus());
                processNodeTaskGetVO.setFlowStatusDesc(FlowStatusEnum.getMemoByType(paasProcessTaskEntity.getFlowStatus()));
            }

            // 是否开启工作流
            boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);
            // 流程操作 未处理或者是被撤回的流程
            if (!Objects.equals(processNodeTaskGetDTO.getFromIndex(),true)){
                if (TaskTypeEnum.UNTREATED.getType().equals(paasProcessNodeTaskEntity.getTaskType())
                        || (FlowStatusEnum.REVOKE.getType().equals(paasProcessTaskEntity.getFlowStatus()) && !TaskTypeEnum.END.getType().equals(paasProcessNodeTaskEntity.getTaskType()))
                        || NodeTypeEnum.START_PROCESS_NODE.getNodeType().equals(paasProcessNodeTaskEntity.getNodeType())
                        || TaskTypeEnum.SYSTEM_COMMIT.getType().equals(paasProcessNodeTaskEntity.getTaskType())) {
                    getProcessOperator(paasProcessTemplateNodeEntityExt, processNodeTaskGetDTO, processNodeTaskGetVO, processTemplate, paasProcessNodeTaskEntity, userMap, openWorkFlow);
                } else {
                    processNodeTaskGetVO.setProcessOperatePermission(new ProcessTemplateNodeVO());
                }
            }

            // 增加流程用时
            long processTime;
            if (paasProcessTaskEntity.getFlowStatus().equals(FlowStatusEnum.PASS.getType())
                    || paasProcessTaskEntity.getFlowStatus().equals(FlowStatusEnum.REJECT.getType())
                    || paasProcessTaskEntity.getFlowStatus().equals(FlowStatusEnum.REFUSE.getType())) {
                processTime = paasProcessTaskEntity.getUpdateTime() - paasProcessTaskEntity.getAddTime();
            } else {
                processTime = DateUtil.getInt() - paasProcessTaskEntity.getAddTime();
            }
            processNodeTaskGetVO.setProcessTime(processTime);

            if (!openWorkFlow) {
                //流程合同比对
                if ((Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) && Objects.equals(processNodeTaskGetDTO.getPlatform(),PlatFormEnum.WEB.getValue())
                        && processType.equals(ProcessTypeEnum.TODO.getValue())){
                    Boolean compareButton = contractCompareUtil.showCompareButton(corpid, processNodeTaskGetDTO.getLoginUser().getPermSet(), processNodeTaskGetDTO.getUserId());
                    if (compareButton) {
                        ProcessOperateVo operatePoJo = new ProcessOperateVo();
                        operatePoJo.setText(TaskTypeEnum.CONTRACT_COMPARE.getMemo());
                        operatePoJo.setFlag(1);
                        operatePoJo.setType(TaskTypeEnum.CONTRACT_COMPARE.getType());
                        processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                    }
                }
                // 流程评论权限
                if (processNodeTaskGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_COMMENT.getAlias())) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(TaskTypeEnum.PROCESS_COMMENT.getMemo());
                    operatePoJo.setFlag(1);
                    operatePoJo.setType(TaskTypeEnum.PROCESS_COMMENT.getType());
                    if (!Objects.equals(processNodeTaskGetDTO.getPlatform(),PlatFormEnum.WEB.getValue())){
                        if (processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size()<3){
                            processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                        }else {
                            processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(2,operatePoJo);
                        }
                    }else {
                        processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                    }

                }
                // ding权限
                if (Objects.equals(processNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) &&
                        (processType.equals(ProcessTypeEnum.TODO.getValue()) || processType.equals(ProcessTypeEnum.CREATE.getValue()))) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText("DING");
                    operatePoJo.setFlag(1);
                    processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate()
                            .add(processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size(), operatePoJo);
                }

            }
            Set<String> loginUserPermSet = processNodeTaskGetDTO.getLoginUser().getPermSet();
            // 移动端添加打印按钮
            PrintProPermissionAliasEnum printProPermissionAliasEnum = PrintProPermissionAliasEnum.getByCode(businessType);
            boolean hasPrint = Objects.nonNull(printProPermissionAliasEnum) && loginUserPermSet.contains(printProPermissionAliasEnum.getAlias());
            if (Objects.equals(processNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) && hasPrint) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setType(TaskTypeEnum.PRINT.getType());
                operatePoJo.setText(I18nMessageUtil.getMessage(PaasConstant.PRINT));
                operatePoJo.setFlag(1);
                if (CollectionsUtil.isNotEmpty(processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate())){
                    processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate()
                            .add(processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size()-1, operatePoJo);
                }
            }

            if (!openWorkFlow) {
                // 删除流程权限
                if ((processNodeTaskGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_DELETE.getAlias())
                        && Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.CREATE.getValue()))
                        || Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.ALL.getValue())) {
                    processNodeTaskGetVO.setDelFlag(1);
                }
                // 低代码按钮
                CustomButtonListDTO customButtonListDTO = new CustomButtonListDTO();
                customButtonListDTO.setBusinessType(processNodeTaskGetDTO.getBusinessType());
                customButtonListDTO.setFormId(formId);
                customButtonListDTO.setSaasMark(processNodeTaskGetDTO.getSaasMark());
                customButtonListDTO.setCorpid(processNodeTaskGetDTO.getCorpid());
                customButtonListDTO.setLoginUser(processNodeTaskGetDTO.getLoginUser());
                customButtonListDTO.setType(ButtonTypeEnum.PROCESS.getCode());
                CustomButtonListVO formCustomButtonListVO = customButtonService.listByPermission(customButtonListDTO);
                List<ProcessButtonVO> processButtonVOList = new ArrayList<>();
                if (Objects.nonNull(formCustomButtonListVO) && CollectionsUtil.isNotEmpty(formCustomButtonListVO.getCustomButtonList())) {
                    formCustomButtonListVO.getCustomButtonList().forEach(item->{
                        ProcessButtonVO buttonPojo = new ProcessButtonVO();
                        buttonPojo.setId(item.getId());
                        buttonPojo.setActionList(item.getActionList());
                        buttonPojo.setName(item.getName());
                        buttonPojo.setAlias(PaasConstant.LOW_CODE);
                        processButtonVOList.add(buttonPojo);
                    });
                }
                processNodeTaskGetVO.getProcessOperatePermission().setLowCodeButton(processButtonVOList);
            }

            // 打印权限
            boolean printFlag;
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.PAAS;
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), processNodeTaskGetDTO.getSaasMark())) {
                printFlag = hasPrintPermission(businessType, processNodeTaskGetDTO.getLoginUser().getPermSet());
                xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            } else {
                UserFormPermissionVO userFormPermissionVO = userService.getUserFormPermissionInternal(corpid,
                        processNodeTaskGetDTO.getUserId(), processNodeTaskGetDTO.getAppId(), processNodeTaskGetDTO.getMenuId());
                PermissionTermsPojo permissionTerms = userFormPermissionVO.getFormPermission().getPermission();
                printFlag = Objects.equals(BasicConstant.ONE, permissionTerms.getPrint()) || processNodeTaskGetDTO.getLoginUser().isAdminOrBoss();
            }

            if (printFlag){
                processNodeTaskGetVO.setPrintFlag(BasicConstant.ONE);
            }
            if (Objects.equals(processNodeTaskGetDTO.getBusinessType(), XbbRefTypeEnum.REFUND.getCode()) && Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType())
                    && Objects.equals(paasFormEntityExt.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())){
                JSONObject data = processNodeTaskGetVO.getData();
                JSONObject orderJson = data.getJSONArray(ReturnEnum.ORDER_ID.getAttr()).getJSONObject(0);
                ContractEntityExt contractEntityExt = contractModel.getByKey(orderJson.getLongValue(StringConstant.SAAS_LINK_BUSINESS_ID), corpid);
                if (contractEntityExt != null) {
                    JSONObject couponData = contractEntityExt.getData();
                    JSONArray couponId = couponData.getJSONArray(OrderEnum.COUPON_ID.getAttr());
                    List<Long> couponIdList = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(couponId)) {
                        for (int i = 0; i < couponId.size(); i++) {
                            couponIdList.add(couponId.getLongValue(i));
                        }
                        List<CouponEntity> coupons = couponModel.findEntitysByIdIn(couponIdList, corpid);
                        if (CollectionUtils.isNotEmpty(coupons)) {
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < coupons.size(); i++) {
                                sb.append(coupons.get(i).getName()).append(",");
                            }
                            sb.deleteCharAt(sb.length() - 1);
                            data.put(ReturnEnum.RETURN_TIPS.getSaasAttr(), sb);
                        }
                    }
                }
            }

            //无需审批或审批通过的数据才可能签署
            if ((Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()) ||
                    Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.PASS.getType()))) {

                UserFormPermissionVO userFormPermissionVO = userService.getUserFormPermissionInternal(corpid,
                        processNodeTaskGetDTO.getUserId(), paasFormEntityExt.getAppId(), paasFormEntityExt.getMenuId());

                if (esignHelp.hasEsignPermission(userFormPermissionVO, processNodeTaskGetDTO.getLoginUser().getPermSet(),
                        xbbRefTypeEnum, corpid, formId)){

                    EsignFlowStatusDTO esignFlowStatusDTO = new EsignFlowStatusDTO();
                    BeanUtil.copyProperties(processNodeTaskGetDTO, esignFlowStatusDTO);
                    esignFlowStatusDTO.setCorpid(corpid);
                    esignFlowStatusDTO.setFormId(formId);
                    esignFlowStatusDTO.setDataId(formDataId);
                    EsignFlowStatusVO esignFlowStatusVO = null;
                    try {
                        esignFlowStatusVO = esignService.getEsignFlowStatus(esignFlowStatusDTO);
                    } catch (XbbException e) {
//                        return ;
                    }
                    Integer code = esignFlowStatusVO.getCode();
                    EsignFlowStatusEnum esignFlowStatusEnum = EsignFlowStatusEnum.getByCode(code);
                    switch (esignFlowStatusEnum) {
                        case COMPLETE:
                        case SIGNING:
                            //没有下载
                            break;
                        case UNSIGNED:
                        case DRAFT:
                        case UNDO:
                        case TERMINATION:
                        case EXPIRED:
                        case REFUSAL:
                            processNodeTaskGetVO.setEsignFlag(BasicConstant.ONE);
                            if (!openWorkFlow) {
                                if (Objects.equals(processNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                                    operatePoJo.setText(TaskTypeEnum.ESIGN.getMemo());
                                    operatePoJo.setFlag(1);
                                    operatePoJo.setType(TaskTypeEnum.ESIGN.getType());
                                    processNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                                }
                            }

                            break;
                        default:
                            break;
                    }
                }

            }
            String formConfigValue = formConfigModel.getConfigValueByRedis(RedisPrefixConstant.ASSIGNMENT_RULES, corpid, formId, processNodeTaskGetDTO.getSaasMark(), processNodeTaskGetDTO.getBusinessType(), "0");
            if (StringUtil.isNotEmpty(formConfigValue)) {
                processNodeTaskGetVO.setAssignmentRules(Integer.valueOf(formConfigValue));
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库流程详情出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        Integer businessType = processNodeTaskGetDTO.getBusinessType();
        String corpid = processNodeTaskGetDTO.getCorpid();
        // 查看是否能使用工商模糊查询
        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType)) {
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
            if (soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
                processNodeTaskGetVO.setIsBusiness(1);
            }
        }
        // 查看是否能使用精线索的工商查询
        if (fineClueHelp.isFineClueByCorpid(corpid, businessType, null)) {
            processNodeTaskGetVO.setIsFineClue(1);
        }
        //精线索工商查询 通过pid控制icon显示
        if(fineClueHelp.hasBusinessSearch(businessType)){
            String companyName = (String) processNodeTaskGetVO.getData().get(ManagementBaseEnum.NAME.getAttr());
            String pid = fineClueHelp.getPidByCompanyName(corpid,companyName,processNodeTaskGetDTO.getPlatform());
            if (Objects.nonNull(pid)) {
                processNodeTaskGetVO.getData().put("pid",pid);
            }
        }
        return processNodeTaskGetVO;
    }

    /**
     * 处理团队成员上线之后，一些业务团队放出来之后，需要在审批那边做个特殊处理兼容一下
     * 具体需要处理的业务有：回款单、付款单、联系人、供应商联系人
     * 回款单：客户（text_6 字符串）、合同（text_4 数组）
     *
     * @param ownIdList 负责人id列表
     * @param coUserIdList 协同人列表
     * @param dataJsonObject 审批数据
     * @param businessType 业务类型
     * @param corpid 公司id
     */
    private void handTeamOldProcessData(JSONArray ownIdList, JSONArray coUserIdList, JSONObject dataJsonObject, Integer businessType, String corpid, Long addTime) {
        boolean specialHandTag = Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode()) ||
                Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.SUPPLIER_CONTACT.getCode());
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        Integer parentBusinessType = null;
        if (specialHandTag) {
            if ((Objects.isNull(ownIdList) || ownIdList.size() == BasicConstant.ZERO) &&
                    (Objects.isNull(coUserIdList) || coUserIdList.size() == BasicConstant.ZERO)) {
                if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) &&
                        (Objects.nonNull(addTime) && addTime > TeamMembersConstant.OLD_TIME_DATA)) {
                    return;
                }
                Map<Long, List<String>> mainUserIdMap = new HashMap<>();
                Map<Long, List<String>> coUserIdMap = new HashMap<>();
                Object customerOrSupplierObj = null;
                Object contractOrSupplierContractObj = null;
                Set<String> userIdList = new HashSet<>();
                switch (xbbRefTypeEnum) {
                    case PAYMENT_SHEET:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                        break;
                    case PAY_SHEET:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(PaySheetEnum.LINK_SUPPLIER.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getJSONArray(PaySheetEnum.LINK_PURCHASE.getAttr());
                        break;
                    case CONTACT:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(ContactEnum.CUSTOMER_NAME.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getString(ContactEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
                        break;
                    case SUPPLIER_CONTACT:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(SupplierContactEnum.SUPPLIER_ID.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getString(SupplierContactEnum.SUPPLIER_ID_LINK_TEXT.getAttr());
                        break;
                }
                //判断contractOrSupplierContractObj是不是为空
                boolean contactOrSupplierContactTag = Objects.equals(XbbRefTypeEnum.CONTACT, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.SUPPLIER_CONTACT, xbbRefTypeEnum);
                boolean preSheetTag = false;
                if(Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.PAY_SHEET, xbbRefTypeEnum)){
                    if(Objects.equals(dataJsonObject.get(PaymentConstant.ATTR_SHEET_TYPE), SheetTypeEnum.PREPAYMENT.getCode())
                            || Objects.equals(dataJsonObject.get(PaymentConstant.ATTR_SHEET_TYPE), SheetTypeEnum.RED_PREPAYMENT.getCode())){
                        //付款单、回款单  如果是预收预付类型，也是获取客户和供应商团队
                        preSheetTag = true;
                    }
                }
                if (contactOrSupplierContactTag || preSheetTag) {
                    boolean flage = true;
                    if (Objects.isNull(customerOrSupplierObj)) {
                        flage = false;
                    }
                    if (!flage) {
                        return;
                    }

                    //说明需要获取客户或供应商的负责人团队
                    if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) ||
                            Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
                        parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
                    }else {
                        parentBusinessType = XbbRefTypeEnum.SUPPLIER.getCode();
                    }
                    if (Objects.nonNull(customerOrSupplierObj)) {
                        businessUserTeamHelp.getUserIdMapSetShow(userIdList, Arrays.asList((long)customerOrSupplierObj), corpid, parentBusinessType, false, mainUserIdMap,
                                coUserIdMap, BasicConstant.ZERO);
                        List<String> mainUserList = mainUserIdMap.get((long)customerOrSupplierObj);
                        List<String> coUserList =  coUserIdMap.get((long)customerOrSupplierObj);
                        packageTeamInfo(mainUserList, coUserList, dataJsonObject, corpid);
                    }
                }

                boolean paymentOrPaymentsheetTag = Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.PAY_SHEET, xbbRefTypeEnum);
                if (paymentOrPaymentsheetTag) {
                    boolean flage = true;
                    if (Objects.isNull(contractOrSupplierContractObj)) {
                        flage = false;
                    }else if (contractOrSupplierContractObj instanceof JSONArray) {
                        if (((JSONArray)contractOrSupplierContractObj).size() == BasicConstant.ZERO) {
                            flage = false;
                        }
                    }
                    if (!flage) {
                        return;
                    }
                    //说明需要获取合同或则采购合同的负责人团队
                    if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())){
                        parentBusinessType = XbbRefTypeEnum.CONTRACT.getCode();
                    }else {
                        parentBusinessType = XbbRefTypeEnum.PURCHASE.getCode();
                    }
                    if (Objects.nonNull(contractOrSupplierContractObj)) {
                        List<Long> dataIdList = JSONObject.parseArray(((JSONArray) contractOrSupplierContractObj).toJSONString(), Long.class);
                        businessUserTeamHelp.getUserIdMapSetShow(userIdList, dataIdList, corpid, parentBusinessType, false, mainUserIdMap,
                                coUserIdMap, BasicConstant.ZERO);
                        List<String> finalOwnerStrList = new ArrayList<>();
                        List<String> finalCoUserStrList = new ArrayList<>();
                        for (Long dataId : dataIdList) {
                            List<String> ownerIdStrList = Objects.isNull(mainUserIdMap.get(dataId)) ? new ArrayList<>() : mainUserIdMap.get(dataId);
                            List<String> coUserIdStrList = Objects.isNull(coUserIdMap.get(dataId)) ? new ArrayList<>() : coUserIdMap.get(dataId);
                            ownerIdStrList.removeAll(finalOwnerStrList);
                            ownerIdStrList.removeAll(finalCoUserStrList);
                            coUserIdStrList.removeAll(finalOwnerStrList);
                            coUserIdStrList.removeAll(finalCoUserStrList);
                            finalOwnerStrList.addAll(ownerIdStrList);
                            finalCoUserStrList.addAll(coUserIdStrList);
                        }
                        packageTeamInfo(finalOwnerStrList, finalCoUserStrList, dataJsonObject, corpid);
                    }
                }
            }
        }

    }

    /**
     * 封装团队返回信息
     *
     * @param finalOwnerStrList
     * @param finalCouserStrList
     * @param dataJsonObject
     * @param corpid
     */
    private void packageTeamInfo(List<String> finalOwnerStrList, List<String> finalCouserStrList, JSONObject dataJsonObject, String corpid) {
        List<String> finalStrList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(finalOwnerStrList)) {
            finalStrList.addAll(finalOwnerStrList);
        }
        if (CollectionsUtil.isNotEmpty(finalCouserStrList)) {
            finalStrList.addAll(finalCouserStrList);
        }
        if (CollectionsUtil.isNotEmpty(finalStrList)) {
            Map<String, UserEntity>  userEntityMap = userModel.getUserEntityMap(corpid, finalStrList, BasicConstant.ONE);
            if (Objects.nonNull(userEntityMap)) {
                if (CollectionsUtil.isNotEmpty(finalOwnerStrList)) {
                    List<ReturnUserAndDepartmentPojo> ownList = new ArrayList<>();
                    for (String userId : finalOwnerStrList) {
                        UserEntity userEntity = userEntityMap.get(userId);
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        if (Objects.nonNull(userEntity)) {
                            BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                            returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                            ownList.add(returnUserAndDepartmentPojo);
                        }
                    }
                    dataJsonObject.put(FieldTypeEnum.OWNERID.getAlias(), ownList);
                }
                if (CollectionsUtil.isNotEmpty(finalCouserStrList)) {
                    List<ReturnUserAndDepartmentPojo> coList = new ArrayList<>();
                    for (String userId : finalCouserStrList) {
                        UserEntity userEntity = userEntityMap.get(userId);
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        if (Objects.nonNull(userEntity)) {
                            BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                            returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                            coList.add(returnUserAndDepartmentPojo);
                        }
                    }
                    dataJsonObject.put(FieldTypeEnum.COUSERID.getAlias(), coList);
                }
            }
        }
    }



    /**
     * 查重渲染审批中的数据
     * @author lijiangren
     * @date 2022-04-06 11 19
     */
    @Override
    public ProcessNodeTaskGetVO duplicateApprovalDetail(ProcessNodeTaskGetDTO processNodeTaskGetDTO,PaasProcessDataEntity formData) throws XbbException {
        ProcessNodeTaskGetVO processNodeTaskGetVO = new ProcessNodeTaskGetVO();
        try {
            // 钉钉工作台特殊处理
            if (processNodeTaskGetDTO.getFromDingtalk()) {
                dealDingtalkParameter(processNodeTaskGetDTO);
            }
            processNodeTaskGetVO.setProcessType(processNodeTaskGetDTO.getProcessType());
            String corpid = processNodeTaskGetDTO.getCorpid();
            Long formId = processNodeTaskGetDTO.getFormId();
            Integer businessType = processNodeTaskGetDTO.getBusinessType();
            Integer saasMark = processNodeTaskGetDTO.getSaasMark();
            Long formDataId = formData.getFormDataId();
            String creatorId = formData.getCreatorId();
            if (!Objects.equals(0L, formDataId)) {
                PaasFormDataEntity paasFormDataEntity = proModelService.getFormDataEntity(corpid, saasMark, businessType, formDataId);
                if (Objects.nonNull(paasFormDataEntity)) {
                    creatorId = paasFormDataEntity.getCreatorId();
                }
            }
            JSONObject dataJsonObject = JSONObject.parseObject(formData.getData());
            processNodeTaskGetVO.setDataId(formDataId);

            // 获取表单实体
            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
            if (paasFormEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            Integer distributorMark = paasFormEntityExt.getDistributorMark();
            processNodeTaskGetVO.setDistributorMark(distributorMark);
            // 获取用户部门容器
            Map<String, Object> params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
            params.remove("del");
            params.put(ParameterConstant.LEAVE_MARKS,BasicConstant.ONE);
            List<UserEntity> userList = userModel.findEntitys(params);
            params.remove(ParameterConstant.LEAVE_MARKS);
            if (userList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            Map<String, UserEntity> userMap = new HashMap<>(userList.size());
            userList.forEach((item) -> userMap.put(item.getUserId(), item));
            params.remove(ParameterConstant.COLUMNS);
            // department不能用del条件，有del = 2的数据
            List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
            if (departmentList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
            }
            Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
            departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

            // 红冲回款，坏账用 防止dataJsonObject 防止转换过程中丢失
            JSONObject oldData = JSONObject.parseObject(formData.getData());
            // 获取表单解释
            PaasFormExplainEntity paasFormExplainEntity = getPaasFormExplain(corpid, formId, businessType, oldData, distributorMark);
            List<FieldAttrEntity> explainList = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

            // 获取当前流程主任务
            PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processNodeTaskGetDTO.getProcessTaskId().intValue(), corpid);
            if (paasProcessTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }

            // 为了产品内的成本高级权限走一遍表单权限format
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            handlerExplainDTO.setOwnerId(Collections.singletonList(formData.getOwnerId()));
            handlerExplainDTO.setCreatorId(creatorId);
            BeanUtil.copyProperties(processNodeTaskGetDTO, handlerExplainDTO, false);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);
            handlerExplainDTO.setFormData(dataJsonObject);
            HandlerExplainVO handlerExplainVO = formDataFormExplainHandleName.handleExplain(handlerExplainDTO);
            if (handlerExplainVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            explainList = handlerExplainVO.getHeadList();

            // 解析数据信息
            // 存入系统字段到data中
            dataJsonObject.put(FieldTypeEnum.SERIALNO.getAlias(), formData.getSerialNo());
            if (formData.getDepartmentId() != null && !Objects.equals(formData.getDepartmentId(), 0L)) {
                dataJsonObject.put(FieldTypeEnum.DEPARTMENTID.getAlias(), formData.getDepartmentId());
            }

            // SaaS特殊处理
            processNodeTaskGetVO.setHeadList(explainList);
            specialDealForSaas(businessType, dataJsonObject, explainList);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>(processNodeTaskGetVO.getHeadList().size());
            String labelAttr = null;
            for (FieldAttrEntity item : processNodeTaskGetVO.getHeadList()) {
                explainMap.put(item.getAttr(), item);
                if (Objects.equals(item.getFieldType(), FieldTypeEnum.LABEL.getType())){
                    labelAttr = item.getAttr();
                }
            }

            // saas业务数据格式转换 调用编辑的回显format
            if (Objects.equals(paasProcessTaskEntity.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, saasAnalysisDataDTO);
                BeanUtil.copyProperties(paasProcessTaskEntity, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setUserId(processNodeTaskGetDTO.getUserId());
                saasAnalysisDataDTO.setForProcess(true);
                if (Objects.equals(distributorMark,DistributorMarkEnum.DISTRIBUTOR.getCode())){
                    saasAnalysisDataDTO.setDistributorMark(distributorMark);
                }
                saasUpdateHelp.formatData(saasAnalysisDataDTO, dataJsonObject);
                if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                    dataJsonObject.putIfAbsent(InventoryEnum.INVENTORY_TYPE.getAttr(), 2);
                }
                formatProductHelp.formatProduct(saasAnalysisDataDTO, dataJsonObject, explainList, false);
            }
            // 解析数据信息
            //兼容一下审批中存储格式不同，负责人有些存对象，有些存字符串，其实想要的是字符串
            JSONArray jsonArray = dataJsonObject.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
            if (Objects.nonNull(jsonArray) && jsonArray.size() > BasicConstant.ZERO) {
                List<String> ownIdStrList = new ArrayList<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    Object obj = jsonArray.get(i);
                    if (obj instanceof String) {
                        ownIdStrList.add((String)obj);
                    }else {
                        String ownIdStr = ((JSONObject)obj).getString(StringConstant.ID);
                        ownIdStrList.add(ownIdStr);
                    }
                }
                dataJsonObject.put(FieldTypeEnum.OWNERID.getAlias(), ownIdStrList);
            }
            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
            BeanUtil.copyProperties(processNodeTaskGetDTO, parseSingleRowDataDTO);
            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
            parseSingleRowDataDTO.setUserMap(userMap);
            parseSingleRowDataDTO.setExplainMap(explainMap);
            parseSingleRowDataDTO.setDataJsonObject(dataJsonObject);
            parseSingleRowDataDTO.setIsProcess(true);
            ParseSingleRowDataVO parseSingleRowDataVO = formDataListNoSubFormAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
            if (parseSingleRowDataVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
            }
            dataJsonObject = parseSingleRowDataVO.getResult();
            // 关联查询
            LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
            // 获取关联数据的信息
            if (linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty()) {
                linkResultDataVO.setData(dataJsonObject);
                linkResultDataVO.setExplainMap(explainMap);
                linkResultDataVO.setExplainList(explainList);
                linkResultDataVO.setUserMap(userMap);
                linkResultDataVO.setDepartmentMap(departmentMap);
                FormDataUpdateGetDTO formDataUpdateDTO = new FormDataUpdateGetDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, formDataUpdateDTO);
                dataJsonObject = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataUpdateDTO, linkResultDataVO);
            }
            // node任务的vo对象
            PaasProcessNodeTaskVO paasProcessNodeTaskVO = new PaasProcessNodeTaskVO();
            paasProcessNodeTaskVO.setSaasMark(paasProcessTaskEntity.getSaasMark());
            paasProcessNodeTaskVO.setBusinessType(paasProcessTaskEntity.getBusinessType());
            UserEntity creator = userMap.get(creatorId);
            if (Objects.nonNull(creator)) {
                UserVO creatorUser = new UserVO();
                BeanUtil.copyProperties(creator, creatorUser);
                paasProcessNodeTaskVO.setCreatorUser(creatorUser);
                dataJsonObject.put(FieldTypeEnum.CREATORID.getAlias(), creator.getName());
            }

            Map<Long, LabelPojo> labelPojoMap = labelHelp.getLabelMap(formId, corpid, processNodeTaskGetDTO.getAppId());
            labelHelp.dealId2Pojo4One(labelAttr,dataJsonObject, labelPojoMap);
            // 创建时间
            dataJsonObject.put(FieldTypeEnum.ADDTIME.getAlias(), formData.getAddTime());
            processNodeTaskGetVO.setName(paasFormEntityExt.getName());
            processNodeTaskGetVO.setData(dataJsonObject);
            processNodeTaskGetVO.setSerialNo(formData.getSerialNo());

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("duplicateApprovalDetail出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskGetVO;
    }
    /**
     * 获取单个审批操作按钮
     * @param processNodeTaskGetDTO
     * @return
     * @throws XbbException
     */
    private void getOperations(ProcessNodeTaskGetDTO processNodeTaskGetDTO,ProcessNodeTaskGet4IndexVO processNodeTaskGet4IndexVO) throws XbbException {
        String corpid = processNodeTaskGetDTO.getCorpid();

        Map<String, UserEntity> userMap = processNodeTaskGetDTO.getUserMap();

        String processType = processNodeTaskGetDTO.getProcessType();
        Long taskId = processNodeTaskGetDTO.getProcessTaskId();
        ProcessNodeTaskGetVO processNodeTaskGetVO = new ProcessNodeTaskGetVO();
        // 检索流程表单数据
        PaasProcessDataEntity formData = paasProcessDataModel.getByTaskId(taskId, corpid);
        if (formData == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        Long formDataId = formData.getFormDataId();
        processNodeTaskGetVO.setDataId(formDataId);
        // 获取当前流程主任务
        PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processNodeTaskGetDTO.getProcessTaskId().intValue(), corpid);
        if (paasProcessTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        UserEntity commitUserEntity = userMap.get(paasProcessTaskEntity.getCreatorId());
        if (Objects.nonNull(commitUserEntity)) {
            UserVO commitUser = new UserVO();
            BeanUtil.copyProperties(commitUserEntity, commitUser);
            processNodeTaskGetVO.setCommitUser(commitUser);
        } else {
            // 人员离职
            UserVO commitUser = new UserVO();
            BeanUtil.copyProperties(processNodeTaskGetDTO.getLoginUser(), commitUser);
            commitUser.setName("***(" + I18nMessageUtil.getMessage(I18nStringConstant.RESIGNED) + ")");
            commitUser.setUserId("0");
            processNodeTaskGetVO.setCommitUser(commitUser);
        }
        // 获取节点数据
        PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = paasProcessNodeTaskModel.getByKey(processNodeTaskGetDTO.getProcessNodeTaskId().intValue(), corpid);
        if (paasProcessNodeTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
        }
        // 查询审批模板
        PaasProcessTemplateEntity processTemplate = paasProcessTemplateModel.getByKey(formData.getTemplateId(), corpid);
        if (processTemplate == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TEMPLATE_NOT_EXIST);
        }

        // 节点模板
        PaasProcessTemplateNodeEntityExt paasProcessTemplateNodeEntityExt = processTemplateNodeModel.getByKey(paasProcessNodeTaskEntity.getTemplateNodeId().intValue(), corpid);
        if (paasProcessTemplateNodeEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
        }
        // 提交给我和抄送给我的用节点状态
        if (Objects.equals(ProcessTypeEnum.TODO.getValue(), processType) || Objects.equals(ProcessTypeEnum.CC.getValue(), processType)) {
            processNodeTaskGetVO.setFlowStatus(paasProcessNodeTaskEntity.getTaskType());
            processNodeTaskGetVO.setFlowStatusDesc(ProcessSearchStatusTodoEnum.getStatusMemo(paasProcessNodeTaskEntity.getTaskType()));
        } else {
            processNodeTaskGetVO.setFlowStatus(paasProcessTaskEntity.getFlowStatus());
            processNodeTaskGetVO.setFlowStatusDesc(FlowStatusEnum.getMemoByType(paasProcessTaskEntity.getFlowStatus()));
        }
        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);
        // 流程操作 未处理或者是被撤回的流程
        if (TaskTypeEnum.UNTREATED.getType().equals(paasProcessNodeTaskEntity.getTaskType())
                || (FlowStatusEnum.REVOKE.getType().equals(paasProcessTaskEntity.getFlowStatus()) && !TaskTypeEnum.END.getType().equals(paasProcessNodeTaskEntity.getTaskType()))
                || NodeTypeEnum.START_PROCESS_NODE.getNodeType().equals(paasProcessNodeTaskEntity.getNodeType())
                || TaskTypeEnum.SYSTEM_COMMIT.getType().equals(paasProcessNodeTaskEntity.getTaskType())) {
            getProcessOperator(paasProcessTemplateNodeEntityExt, processNodeTaskGetDTO, processNodeTaskGetVO, processTemplate, paasProcessNodeTaskEntity, userMap, openWorkFlow);
        } else {
            processNodeTaskGetVO.setProcessOperatePermission(new ProcessTemplateNodeVO());
        }
        ProcessNodeTaskOperatePojo operatePojo = new ProcessNodeTaskOperatePojo();
        operatePojo.setProcessTaskId(processNodeTaskGetDTO.getProcessTaskId());
        operatePojo.setProcessOperatePermission(processNodeTaskGetVO.getProcessOperatePermission());
        processNodeTaskGet4IndexVO.setProcessNodeTaskOperatePojo(operatePojo);
    }

    /**
     * 异或的解释处理
     * @param explainList
     * @param fieldPermissionEntityList
     * @return
     */
    private List<FieldAttrEntity> xorExplainListByFieldPermission(List<FieldAttrEntity> explainList, List<FieldPermissionEntityExt> fieldPermissionEntityList, UserVO loginUser) {
        List<FieldAttrEntity> headList = new ArrayList<>();
        try {
            Map<String, FieldPermissionEntityExt> fieldPermissionMap = new HashMap<>(fieldPermissionEntityList.size());
            fieldPermissionEntityList.forEach((item)->{
                if(StringUtil.isNotEmpty(item.getSubAttr())){
                    fieldPermissionMap.put(item.getAttr()+"."+item.getSubAttr(), item);
                }else{
                    fieldPermissionMap.put(item.getAttr(), item);
                }
            });
            headList = ProcessUtil.xorExplainListByFieldPermission(explainList, fieldPermissionMap, null, false, loginUser);
        }catch (Exception e) {
            LOG.error("获取字段权限出错：", e);
        }
        return headList;
    }

    private void specialDealForSaas(Integer businessType, JSONObject dataJsonObject, List<FieldAttrEntity> explainList) throws XbbException {
        if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
            // 红冲发票解释处理和data处理
            String orginIdAttr = InvoiceEnum.ORIGIN_ID.getAttr();
            Integer originId = dataJsonObject.getInteger(orginIdAttr);
            if (originId != null && originId > 0) {
               explainList.forEach(item -> {
                   if (Objects.equals(item.getAttr(), orginIdAttr)) {
                       item.setShowType(ShowTypeEnum.ALL.getCode());
                       item.setEditable(0);
                   } else if (Objects.equals(item.getAttr(), InvoiceEnum.CUSTOMER_NAME.getAttr())) {
                       item.setEditable(0);
                   }
               });
               showFormatHelp.formatLinkBusiness4Show(dataJsonObject, orginIdAttr, InvoiceEnum.ORIGIN_ID_LINK_TEXT.getAttr(), InvoiceEnum.ORIGIN_ID.getFieldType());
            }
        }
    }

    /**
     * 获取解释
     * @param corpid
     * @param formId
     * @param businessType
     * @param oldData
     * @param distributorMark
     * @return
     * @throws XbbException
     */
    private PaasFormExplainEntity getPaasFormExplain(String corpid, Long formId, Integer businessType, JSONObject oldData, Integer distributorMark) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            //预收/付款余额的formId可能不是回/付款单模板的id
            paasFormExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(businessType, corpid, distributorMark);
        }
        // 付款的支付方式是隐藏的，没法改，所以先不读
        /*else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            paasFormExplainEntity = paasFormExplainModel.getSystemDefaultExplain(XbbRefTypeEnum.PAY_SHEET.getCode());
            // 郑风说要根据付款的支付方式联动修改这个
            PaasFormExplainEntity payPlanExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PAY_PLAN.getCode(), corpid);
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(payPlanExplainEntity.getExplains(), PayPlanEnum.PAYMENT_METHOD.getAttr());
            List<FieldAttrEntity> explainList = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                String attr = fieldAttrEntity.getAttr();
                if (Objects.equals(attr, PaySheetEnum.PAY_TYPE.getAttr())) {
                    fieldAttrEntity.setItems(explainMap.getOrDefault(PayPlanEnum.PAYMENT_METHOD.getAttr(), new FieldAttrEntity()).getItems());
                }
            }
            paasFormExplainEntity.setExplains(JSON.toJSONString(explainList));
        }*/ else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
            if (workOrderExplainEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
            paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            paasFormExplainEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        } else {
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        }
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        return paasFormExplainEntity;
    }

    @Override
    public ProcessNodeTaskListVO createList(ProcessNodeTaskListDTO processNodeTaskListDTO) throws XbbException {
        ProcessNodeTaskListVO processNodeTaskListVO = new ProcessNodeTaskListVO();
        try {
            if (!processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_APP.getAlias())
                    || !processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS.getAlias())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAVE_NO_PERMISSION);
            }
            Map<String, Object> param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            // SaaS业务处理
            getSaasBusinessType(processNodeTaskListDTO, param);
            if (processNodeTaskListDTO.getCommitTime() != null) {
                getTimeRange(processNodeTaskListDTO, param);
            }
            //审批编号搜索
            if(StringUtil.isNotEmpty(processNodeTaskListDTO.getSerialNoLike())){
                boolean fuzzyMatchSerialNo = fuzzyMatchSerialNo(processNodeTaskListDTO.getCorpid());
                if (fuzzyMatchSerialNo) {
                    param.put("serialNoMatch",processNodeTaskListDTO.getSerialNoLike());
                } else {
                    param.put("serialNoLike",processNodeTaskListDTO.getSerialNoLike());
                }
            }
            param.put("creatorId", processNodeTaskListDTO.getUserId());
            param.put("orderByStr", " add_time desc");
            // 单据拆分兼容处理
            specialParams(param, processNodeTaskListDTO.getBusinessType());
            PageHelper pageHelper = new PageHelper(processNodeTaskListDTO.getPage(), processNodeTaskListDTO.getPageSize());
            if (processNodeTaskListDTO.getPageSize() <= PaasConstant.APPROVAL_INDEX_SIZE){
                pageHelper.setPageSize(PaasConstant.APPROVAL_INDEX_SIZE + 1);
                param.put("pageSize",PaasConstant.APPROVAL_INDEX_SIZE + 1);
            }
            List<PaasProcessTaskEntity> taskList = (List<PaasProcessTaskEntity>) PageHelperUtil.getEntityList(param, pageHelper, paasProcessTaskModel);
            if (taskList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }
            if (isEmptyList(processNodeTaskListDTO, processNodeTaskListVO, taskList)) {
                return processNodeTaskListVO;
            }
            Map<Long, PaasProcessTaskEntity> processTaskMap = new HashMap<>(taskList.size());
            List<Long> taskIdInList = new ArrayList<>();
            taskList.forEach((item) -> {
                taskIdInList.add(item.getId());
                processTaskMap.put(item.getId(), item);
            });
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            param.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            param.put("taskIdIn", taskIdInList);
            //param.remove("creatorId");
            // 确保节点为最新节点
            param.put("orderByStr", " update_time " + SortOrder.DESC + ", id " + SortOrder.DESC);
            //param.remove("pageNum");
            //param.remove("start");
            List<PaasProcessNodeTaskEntityExt> list = paasProcessNodeTaskModel.getLatestNodeForList(param);
            if (list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            boolean hasNode = false;
            PaasProcessNodeTaskEntityExt nodeTaskEntityExt = null;
            if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : list) {
                    if (Objects.equals(paasProcessNodeTaskEntityExt.getId(), processNodeTaskListDTO.getProcessNodeTaskId())) {
                        hasNode = true;
                        nodeTaskEntityExt = paasProcessNodeTaskEntityExt;
                        break;
                    }
                }
            }
            if (hasNode) {
                list.remove(nodeTaskEntityExt);
                list.add(0, nodeTaskEntityExt);
            } else if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                param.clear();
                param.put("corpid", processNodeTaskListDTO.getCorpid());
                param.put("del", 0);
                param.put("id", processNodeTaskListDTO.getProcessNodeTaskId());
                List<PaasProcessNodeTaskEntityExt> paasProcessNodeTaskEntityList = paasProcessNodeTaskModel.findEntitys(param);
                if (paasProcessNodeTaskEntityList != null && !paasProcessNodeTaskEntityList.isEmpty()) {
                    list.add(0, paasProcessNodeTaskEntityList.get(0));
                }
            }
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            List<Long> templateNodeIdIn = new ArrayList<>();
            templateNodeIdIn.add(-1L);
            list.forEach(item -> templateNodeIdIn.add(item.getTemplateNodeId()));
            param.put("idIn", templateNodeIdIn);
            //param.put("type", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            param.remove("del");
            List<PaasProcessTemplateNodeEntityExt> nodeList = processTemplateNodeModel.list(param);
            if (nodeList == null || nodeList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            Map<Long, PaasProcessTemplateNodeEntityExt> nodeMap = new HashMap<>(nodeList.size());
            for (PaasProcessTemplateNodeEntityExt templateNode : nodeList) {
                nodeMap.put(templateNode.getId(), templateNode);
            }
            List<SummaryDataVO> summaryList = getSummaryList(processNodeTaskListDTO, nodeMap, processTaskMap, list);
            if (processNodeTaskListDTO.getPageSize() <= PaasConstant.APPROVAL_INDEX_SIZE){
                pageHelper.setRowsCount(summaryList.size());
                if (summaryList.size() > PaasConstant.APPROVAL_INDEX_SIZE){
                    summaryList = summaryList.subList(0,PaasConstant.APPROVAL_INDEX_SIZE);
                }
            }
            processNodeTaskListVO.setList(summaryList);
            processNodeTaskListVO.setPageHelper(pageHelper);
            processNodeTaskListVO.setProcessType(processNodeTaskListDTO.getProcessType());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取我创建的流程数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskListVO;
    }

    @Override
    public ProcessNodeTaskListVO todoList(ProcessNodeTaskListDTO processNodeTaskListDTO) throws XbbException {
        ProcessNodeTaskListVO processNodeTaskListVO = new ProcessNodeTaskListVO();
        try {
            if (!processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_APP.getAlias())
                    || !processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS.getAlias())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAVE_NO_PERMISSION);
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 关联查询条件封装
            getCommonParamForJoinSearch(processNodeTaskListDTO, param);

            // 先根据更新时间降序，再根据id降序
            param.put("orderByStr", " a.update_time " + SortOrder.DESC + ", a.id " + SortOrder.DESC);
            param.put("a_nodeType", NodeTypeEnum.PROCESS_NODE.getNodeType());

            // 审批状态筛选
            if (Objects.isNull(processNodeTaskListDTO.getTaskType())) {
                List<Integer> taskTypeInList = new ArrayList<>();
                taskTypeInList.add(TaskTypeEnum.UNTREATED.getType());
                taskTypeInList.add(TaskTypeEnum.COMMIT.getType());
                taskTypeInList.add(TaskTypeEnum.TRANSFER.getType());
                taskTypeInList.add(TaskTypeEnum.BACK.getType());
                taskTypeInList.add(TaskTypeEnum.END.getType());
                param.put("a_taskTypeIn", taskTypeInList);
            } else {
                param.put("a_taskType", processNodeTaskListDTO.getTaskType());
            }
            // 分页逻辑
            Integer page = processNodeTaskListDTO.getPage();
            Integer pageSize = processNodeTaskListDTO.getPageSize();
            if (page == null || page < 1) {
                page = 1;
            }
            if (pageSize == null || pageSize < 1) {
                pageSize = PageConstant.DEFAULT_PAGE_SIZE;
            }
            param.put("start", (page - 1) * pageSize);
            param.put("pageNum", pageSize);
            Boolean fromIndex = false;
            if (pageSize <= PaasConstant.APPROVAL_INDEX_SIZE){
                fromIndex = true;
                param.put("start", (page - 1) * (PaasConstant.APPROVAL_INDEX_SIZE  + 1));
                param.put("pageNum", (PaasConstant.APPROVAL_INDEX_SIZE  + 1));
            }
            List<PaasProcessNodeTaskEntityExt> nodeTaskList = paasProcessNodeTaskModel.getJoinNodeForList(param);
            if (nodeTaskList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            boolean hasNode = false;
            PaasProcessNodeTaskEntityExt nodeTaskEntityExt = null;
            if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : nodeTaskList) {
                    if (Objects.equals(paasProcessNodeTaskEntityExt.getId(), processNodeTaskListDTO.getProcessNodeTaskId())) {
                        hasNode = true;
                        nodeTaskEntityExt = paasProcessNodeTaskEntityExt;
                        break;
                    }
                }
            }
            if (hasNode) {
                nodeTaskList.remove(nodeTaskEntityExt);
                nodeTaskList.add(0, nodeTaskEntityExt);
            } else if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                param.clear();
                param.put("corpid", processNodeTaskListDTO.getCorpid());
                param.put("del", 0);
                param.put("id", processNodeTaskListDTO.getProcessNodeTaskId());
                List<PaasProcessNodeTaskEntityExt> paasProcessNodeTaskEntityList = paasProcessNodeTaskModel.findEntitys(param);
                if (paasProcessNodeTaskEntityList != null && !paasProcessNodeTaskEntityList.isEmpty()) {
                    nodeTaskList.add(0, paasProcessNodeTaskEntityList.get(0));
                }
            }
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            param.remove("businessType");
            // 分页就不需要这么多数据
            Map<Long, PaasProcessTaskEntity> pageProcessTaskMap = new HashMap<>(nodeTaskList.size());
            List<Long> templateNodeIdIn = new ArrayList<>();
            List<Long> taskIdIn = new ArrayList<>();
            templateNodeIdIn.add(-1L);
            taskIdIn.add(-1L);
            nodeTaskList.forEach(item -> {
                taskIdIn.add(item.getTaskId());
                templateNodeIdIn.add(item.getTemplateNodeId());
            });
            param.put("idIn", templateNodeIdIn);
            List<PaasProcessTemplateNodeEntityExt> nodeList = processTemplateNodeModel.list(param);
            param.put("idIn", taskIdIn);
            param.remove("del");
            List<PaasProcessTaskEntity> taskList = paasProcessTaskModel.list(param);
            taskList.forEach(item -> pageProcessTaskMap.put(item.getId(), item));
            Map<Long, PaasProcessTemplateNodeEntityExt> nodeMap = new HashMap<>(nodeList.size());
            for (PaasProcessTemplateNodeEntityExt templateNode : nodeList) {
                nodeMap.put(templateNode.getId(), templateNode);
            }
            // 移动端不需要处理审批历史和操作按钮
            if (Objects.equals(processNodeTaskListDTO.getPlatform(),PlatFormEnum.DINGTALK.getValue())){
                fromIndex = false;
            }
            // 获取任务中摘要、任务、表单数据
            List<SummaryDataVO> summaryList = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(nodeTaskList)) {
                summaryList = getSummaryList(processNodeTaskListDTO, nodeMap, pageProcessTaskMap, nodeTaskList);
            }
            PageHelper pageHelper = new PageHelper(page, pageSize);
            if (pageSize <= PaasConstant.APPROVAL_INDEX_SIZE){
                pageHelper.setRowsCount(summaryList.size());
                if (summaryList.size() > PaasConstant.APPROVAL_INDEX_SIZE){
                    summaryList = summaryList.subList(0,PaasConstant.APPROVAL_INDEX_SIZE);
                }
            }
            processNodeTaskListVO.setList(summaryList);
            processNodeTaskListVO.setPageHelper(pageHelper);
            processNodeTaskListVO.setProcessType(processNodeTaskListDTO.getProcessType());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库流程任务列表出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskListVO;
    }

    /**
     * 判断该公司是否支持模糊查询
     * @param corpid
     * @return
     */
    private boolean fuzzyMatchSerialNo(String corpid) {
        String alias = CompanyConfigEnum.PROCESS_SERIAL_NO_SEARCH.getAlias();
        String fuzzyMatch = paasRedisHelper.getValue(alias, corpid);
        if (StringUtil.isEmpty(fuzzyMatch)) {
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias( alias,corpid);
            if (Objects.nonNull(companyConfigEntity)) {
                fuzzyMatch = companyConfigEntity.getConfigValue();
            } else {
                fuzzyMatch = BasicConstant.ZERO_STRING;
            }
            paasRedisHelper.setValue(alias, corpid, fuzzyMatch, RedisTimeConstant.TEN_MINUTES);
        }
        return Objects.equals(fuzzyMatch, BasicConstant.ONE_STRING);
    }
    private void getCommonParamForJoinSearch(ProcessNodeTaskListDTO processNodeTaskListDTO, Map<String, Object> param) throws XbbException {
        String corpid = processNodeTaskListDTO.getCorpid();
        Integer businessType = processNodeTaskListDTO.getBusinessType();
        param.put("a_del", 0);
        param.put("b_del", 0);
        param.put("a_corpid", corpid);
        param.put("b_corpid", corpid);
        param.put("a_appId", processNodeTaskListDTO.getAppId());
        param.put("a_menuId", processNodeTaskListDTO.getMenuId());
        param.put("a_userId", processNodeTaskListDTO.getUserId());
        if (StringUtil.isNotEmpty(processNodeTaskListDTO.getCommitUserId())) {
            param.put("b_creatorId", processNodeTaskListDTO.getCommitUserId());
        }
        if (StringUtil.isNotEmpty(processNodeTaskListDTO.getSerialNoLike())) {
            boolean fuzzyMatchSerialNo = fuzzyMatchSerialNo(corpid);
            if (fuzzyMatchSerialNo) {
                param.put("c_serialNoMatch", processNodeTaskListDTO.getSerialNoLike());
            } else {
                param.put("c_serialNoLike", processNodeTaskListDTO.getSerialNoLike());
            }
        }
        // 应用和表单筛选处理
        if (Objects.equals(processNodeTaskListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // saas应用下也可能有paas的自定义表单 所以需要去掉saasMark
            processNodeTaskListDTO.setSaasMark(null);
            Integer saasAppType = processNodeTaskListDTO.getSaasAppType();
            param.remove("saasMark");
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.equals(saasAppType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                params.put("corpid", processNodeTaskListDTO.getCorpid());
                params.put("appId", processNodeTaskListDTO.getAppId());
                params.put("del", 0);
                List<WorkOrderFormEntity> workOrderFormEntities = workOrderFormModel.findEntitys(params);
                if (workOrderFormEntities.size() > 0) {
                    List<Long> formIdList = new ArrayList<>();
                    workOrderFormEntities.forEach(item -> formIdList.add(item.getId()));
                    param.put("a_formIdIn", formIdList);
                }
            } else {
                params.put("corpid", processNodeTaskListDTO.getCorpid());
                params.put("appId", processNodeTaskListDTO.getAppId());
                if (StockConstant.EXCLUDE_INSTOCK_TYPE_LIST.contains(businessType)){
                    List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.OTHER_INSTOCK.getCode(),businessType);
                    params.put("businessTypeList",businessTypeIn);
                } else if (StockConstant.EXCLUDE_OUTSTOCK_TYPE_LIST.contains(businessType)){
                    List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),businessType);
                    params.put("businessTypeList",businessTypeIn);
                } else {
                    params.put("businessType", businessType);
                }
                params.put("del", 0);
                List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.list(params);
                if (paasFormEntityExts.size() > 0) {
                    List<Long> formIdList = new ArrayList<>();
                    paasFormEntityExts.forEach(item -> formIdList.add(item.getId()));
                    param.put("a_formIdIn", formIdList);
                }
            }
        }

        List<Integer> typeEnumInteger;
        if (StockConstant.INSTOCK_TYPE_LIST.contains(businessType)) {
            typeEnumInteger = InstockTypeEnum.getInstockTypeEnumsByStockBusinessType(businessType);
            param.put("b_stockTypeIn",typeEnumInteger);
        } else if (StockConstant.OUTSTOCK_TYPE_LIST.contains(businessType)){
            typeEnumInteger = OutstockTypeEnum.getOutstockTypeEnumsByStockBusinessType(businessType);
            param.put("b_stockTypeIn",typeEnumInteger);
        }
        // 提交时间筛选
        if (Objects.nonNull(processNodeTaskListDTO.getCommitTime())) {
            if (processNodeTaskListDTO.getCommitTime().size() == BasicConstant.ONE) {
                List<Object> commitTime = PaasDateUtil.computeTime(processNodeTaskListDTO.getCommitTime());
                Long startTime = Long.valueOf(commitTime.get(0).toString());
                Long endTime = Long.valueOf(commitTime.get(1).toString());
                param.put("b_startTime", startTime);
                param.put("b_endTime", endTime);
            } else if (processNodeTaskListDTO.getCommitTime().size() == BasicConstant.TWO) {
                Long startTime = Long.valueOf(processNodeTaskListDTO.getCommitTime().get(0).toString());
                Long endTime = Long.valueOf(processNodeTaskListDTO.getCommitTime().get(1).toString());
                param.put("b_startTime", startTime / 1000);
                param.put("b_endTime", endTime / 1000);
            }
        }
        if (Objects.nonNull(processNodeTaskListDTO.getFlowStatus())) {
            param.put("b_flowStatus", processNodeTaskListDTO.getFlowStatus());
        }
    }

    @Override
    public ProcessNodeTaskListVO ccList(ProcessNodeTaskListDTO processNodeTaskListDTO) throws XbbException {
        ProcessNodeTaskListVO processNodeTaskListVO = new ProcessNodeTaskListVO();
        try {
            if (!processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_APP.getAlias())
                    || !processNodeTaskListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS.getAlias())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAVE_NO_PERMISSION);
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 关联查询条件封装
            getCommonParamForJoinSearch(processNodeTaskListDTO, param);
            // 先根据更新时间降序，再根据id降序
            param.put("orderByStr", " a.update_time " + SortOrder.DESC + ", a.id " + SortOrder.DESC);
            param.put("a_taskType", TaskTypeEnum.CC.getType());

            // 分页逻辑
            Integer page = processNodeTaskListDTO.getPage();
            Integer pageSize = processNodeTaskListDTO.getPageSize();
            if (page == null || page < 1) {
                page = 1;
            }
            if (pageSize == null || pageSize < 1) {
                pageSize = PageConstant.DEFAULT_PAGE_SIZE;
            }
            param.put("start", (page - 1) * pageSize);
            param.put("pageNum", pageSize);
            List<PaasProcessNodeTaskEntityExt> nodeTaskList = paasProcessNodeTaskModel.getJoinNodeForList(param);

            if (nodeTaskList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            boolean hasNode = false;
            PaasProcessNodeTaskEntityExt nodeTaskEntityExt = null;
            if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : nodeTaskList) {
                    if (Objects.equals(paasProcessNodeTaskEntityExt.getId(), processNodeTaskListDTO.getProcessNodeTaskId())) {
                        hasNode = true;
                        nodeTaskEntityExt = paasProcessNodeTaskEntityExt;
                        break;
                    }
                }
            }
            if (hasNode) {
                nodeTaskList.remove(nodeTaskEntityExt);
                nodeTaskList.add(0, nodeTaskEntityExt);
            } else if (Objects.nonNull(processNodeTaskListDTO.getProcessNodeTaskId())) {
                param.clear();
                param.put("corpid", processNodeTaskListDTO.getCorpid());
                param.put("del", 0);
                param.put("id", processNodeTaskListDTO.getProcessNodeTaskId());
                List<PaasProcessNodeTaskEntityExt> paasProcessNodeTaskEntityList = paasProcessNodeTaskModel.findEntitys(param);
                if (paasProcessNodeTaskEntityList != null && !paasProcessNodeTaskEntityList.isEmpty()) {
                    nodeTaskList.add(0, paasProcessNodeTaskEntityList.get(0));
                }
            }
            param = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            param.remove("businessType");
            // 分页就不需要这么多数据
            Map<Long, PaasProcessTaskEntity> pageProcessTaskMap = new HashMap<>(nodeTaskList.size());
            List<Long> templateNodeIdIn = new ArrayList<>();
            List<Long> taskIdIn = new ArrayList<>();
            templateNodeIdIn.add(-1L);
            taskIdIn.add(-1L);
            nodeTaskList.forEach(item -> {
                taskIdIn.add(item.getTaskId());
                templateNodeIdIn.add(item.getTemplateNodeId());
            });
            param.put("idIn", templateNodeIdIn);
            List<PaasProcessTemplateNodeEntityExt> nodeList = processTemplateNodeModel.list(param);
            param.put("idIn", taskIdIn);
            List<PaasProcessTaskEntity> taskList = paasProcessTaskModel.list(param);
            taskList.forEach(item -> pageProcessTaskMap.put(item.getId(), item));
            Map<Long, PaasProcessTemplateNodeEntityExt> nodeMap = new HashMap<>(nodeList.size());
            for (PaasProcessTemplateNodeEntityExt templateNode : nodeList) {
                nodeMap.put(templateNode.getId(), templateNode);
            }
            // 获取任务中摘要、任务、表单数据
            if (nodeTaskList.isEmpty()) {
                processNodeTaskListVO.setList(new ArrayList<>());
            } else {
                List<SummaryDataVO> summaryList = getSummaryList(processNodeTaskListDTO, nodeMap, pageProcessTaskMap, nodeTaskList);
                processNodeTaskListVO.setList(summaryList);
            }
            processNodeTaskListVO.setPageHelper(new PageHelper(page, pageSize));
            processNodeTaskListVO.setProcessType(processNodeTaskListDTO.getProcessType());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库流程任务列表出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskListVO;
    }

    /**
     * 审批记录和抄送人列表
     *
     * @param processNodeTaskGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ProcessNodeTaskRecordsVO records(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskRecordsVO processNodeTaskRecordsVO = new ProcessNodeTaskRecordsVO();
        ProcessNodeTaskGetVO processNodeTaskGetVO = new ProcessNodeTaskGetVO();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 钉钉工作台特殊处理
        if (processNodeTaskGetDTO.getFromDingtalk()) {
            dealDingtalkParameter(processNodeTaskGetDTO);
        }
        // 不加del条件 以免离职的问题出现
        params.put(StringConstant.CORPID, processNodeTaskGetDTO.getCorpid());
        List<UserEntity> userList = userModel.findEntitys(params);
        if (userList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
        }
        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> {
            if (Objects.equals(item.getDel(), 1)) {
                item.setName(item.getName() + "(" + I18nMessageUtil.getMessage(I18nStringConstant.RESIGNED)+ ")");
            }
            userMap.put(item.getUserId(), item);
        });

        // 获取当前流程主任务
        PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processNodeTaskGetDTO.getProcessTaskId().intValue(), processNodeTaskGetDTO.getCorpid());
        if (paasProcessTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }
        // 获取流程起始节点提交人信息
        UserEntity commitUserEntity = userMap.get(paasProcessTaskEntity.getCreatorId());

        if (commitUserEntity != null) {
            UserVO commitUser = new UserVO();
            BeanUtil.copyProperties(commitUserEntity, commitUser);
            processNodeTaskGetVO.setCommitUser(commitUser);
        }

        // 获取审批记录
        params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
        params.put("taskId", processNodeTaskGetDTO.getProcessTaskId());
        params.put("orderByStr", "update_time " + SortOrder.ASC + ", id " + SortOrder.ASC);
        List<PaasProcessNodeTaskEntityExt> nodeTaskList = paasProcessNodeTaskModel.findEntitys(params);
        getProcessNodeTaskLogList(nodeTaskList, userMap, processNodeTaskGetVO, processNodeTaskGetDTO);
        BeanUtil.copyProperties(processNodeTaskGetVO, processNodeTaskRecordsVO);
        return processNodeTaskRecordsVO;
    }

    /**
     * 多个审批的审批记录和抄送人列表
     *
     * @param processNodeTaskGetDTO
     * @return
     * @throws XbbException
     */
    private void getLogs(ProcessNodeTaskGetDTO processNodeTaskGetDTO,ProcessNodeTaskGet4IndexVO processNodeTaskGet4IndexVO) throws XbbException{

        String corpid = processNodeTaskGetDTO.getCorpid();
        ProcessNodeTaskGetVO processNodeTaskGetVO = new ProcessNodeTaskGetVO();

        // 钉钉工作台特殊处理
        if (processNodeTaskGetDTO.getFromDingtalk()) {
            dealDingtalkParameter(processNodeTaskGetDTO);
        }
        Map<String, UserEntity> userMap = processNodeTaskGetDTO.getUserMap();

        // 获取当前流程主任务
        PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processNodeTaskGetDTO.getProcessTaskId().intValue(),processNodeTaskGetDTO.getCorpid());
        if (null == paasProcessTaskEntity) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
        }

        // 获取流程起始节点提交人信息
        UserEntity commitUserEntity = userMap.get(paasProcessTaskEntity.getCreatorId());

        if (commitUserEntity != null) {
            UserVO commitUser = new UserVO();
            BeanUtil.copyProperties(commitUserEntity, commitUser);
            processNodeTaskGetVO.setCommitUser(commitUser);
        }
        // 获取审批记录
        Map<String, Object> params;
        params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
        params.put("taskId", paasProcessTaskEntity.getId());
        params.put("orderByStr", "update_time " + SortOrder.ASC + ", id " + SortOrder.ASC);
        params.put("corpid", corpid);
        params.put("del", 0);
        List<PaasProcessNodeTaskEntityExt> nodeTaskList = paasProcessNodeTaskModel.findEntitys(params);
        getProcessNodeTaskLogList(nodeTaskList, userMap, processNodeTaskGetVO, processNodeTaskGetDTO);
        ProcessNodeTaskRecordsPojo processNodeTaskRecordsPojo = new ProcessNodeTaskRecordsPojo();
        BeanUtil.copyProperties(processNodeTaskGetVO,processNodeTaskRecordsPojo);
        processNodeTaskRecordsPojo.setProcessTaskId(processNodeTaskGetDTO.getProcessTaskId());

        processNodeTaskGet4IndexVO.setProcessNodeTaskRecordsPojo(processNodeTaskRecordsPojo);

    }



    @Override
    public SummaryDataVO summaryItem(ProcessNodeItemDTO processNodeItemDTO) throws XbbException {
        SummaryDataVO summaryDataVO;
        String corpid = processNodeItemDTO.getCorpid();
        try {
            PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = paasProcessNodeTaskModel.getByKey(processNodeItemDTO.getNodeTaskId().intValue(), corpid);
            if (paasProcessNodeTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            Long taskId = paasProcessNodeTaskEntity.getTaskId();
            PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(taskId.intValue(), corpid);
            if (paasProcessTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }
            // 检索表单数据
            PaasProcessDataEntity formData = paasProcessDataModel.getByTaskId(taskId, corpid);
            if (formData == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            // 表单是否存在
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            if (Objects.equals(paasProcessTaskEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formData.getFormId(), corpid);
                if (workOrderFormEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
                paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formData.getFormId(), corpid);
            }
            if (paasFormEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // 表单解释是否存在
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);
                if (workOrderExplainEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
                paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormExplainEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);
            }
            if (paasFormExplainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // 节点模板
            PaasProcessTemplateNodeEntityExt paasProcessTemplateNodeEntityExt = processTemplateNodeModel.getByKey(paasProcessNodeTaskEntity.getTemplateNodeId().intValue(), corpid);
            if (paasProcessTemplateNodeEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            // 用户列表
            Map<String, Object> params = BeanUtil.convertBean2Map(processNodeItemDTO, true);
            List<UserEntity> allUser = userModel.findEntitys(params);
            if (allUser == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            Map<String, UserEntity> userMap = new HashMap<>(allUser.size());
            allUser.forEach((item) -> userMap.put(item.getUserId(), item));
            // 部门列表
            params.remove(ParameterConstant.COLUMNS);
            List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
            if (departmentList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
            }
            Map<String, DepartmentEntity> departmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));
            SummaryDataDTO summaryDataDTO = new SummaryDataDTO();
            BeanUtil.copyProperties(processNodeItemDTO, summaryDataDTO);
            summaryDataDTO.setTaskId(taskId);
            summaryDataDTO.setMenuId(paasProcessNodeTaskEntity.getMenuId());
            summaryDataDTO.setCorpid(corpid);
            summaryDataDTO.setPaasProcessDataEntity(formData);
            summaryDataDTO.setPaasFormExplainEntity(paasFormExplainEntity);
            summaryDataDTO.setSummaryEntityList(paasProcessTemplateNodeEntityExt.getFieldPermissionList());
            summaryDataDTO.setUserId(processNodeItemDTO.getUserId());
            summaryDataDTO.setPaasProcessTaskEntity(paasProcessTaskEntity);
            summaryDataDTO.setDepartmentMap(departmentMap);
            summaryDataDTO.setUserMap(userMap);
            summaryDataVO = paasProcessDataService.getSummaryAndTitle(summaryDataDTO);
            PaasProcessNodeTaskVO paasProcessNodeTaskVO = new PaasProcessNodeTaskVO();
            BeanUtil.copyProperties(paasProcessNodeTaskEntity, paasProcessNodeTaskVO);
            paasProcessNodeTaskVO.setSaasMark(paasProcessTaskEntity.getSaasMark());
            paasProcessNodeTaskVO.setBusinessType(paasProcessTaskEntity.getBusinessType());
            paasProcessNodeTaskVO.setOpinionFlag(paasProcessTemplateNodeEntityExt.getOpinionFlag());
            paasProcessNodeTaskVO.setCreatorId(paasProcessTaskEntity.getCreatorId());
            paasProcessNodeTaskVO.setProcessType(processNodeItemDTO.getProcessType());
            ProcessNodeTaskGetDTO processNodeTaskGetDTO = new ProcessNodeTaskGetDTO();
            BeanUtil.copyProperties(processNodeItemDTO, processNodeTaskGetDTO);
            getUserName(processNodeTaskGetDTO, paasProcessNodeTaskVO);
            UserVO operatorUser = paasProcessNodeTaskVO.getOperatorUser();
            if (TaskTypeEnum.UNTREATED.getType().equals(paasProcessNodeTaskVO.getTaskType())
                    && processNodeTaskGetDTO.getUserId().equals(operatorUser.getUserId())) {
                paasProcessNodeTaskVO.setTaskTypeMemo(I18nMessageUtil.getMessage(PaasConstant.WAITING_FOR_ME_TO_APPROVE));
            } else {
                paasProcessNodeTaskVO.setTaskTypeMemo(ProcessSearchStatusTodoEnum.getStatusMemo(paasProcessNodeTaskVO.getTaskType()));
            }
            TaskTypeEnum typeEnum = TaskTypeEnum.getTaskTypeEnum(paasProcessNodeTaskVO.getTaskType());
            if (typeEnum != null) {
                paasProcessNodeTaskVO.setColor(typeEnum.getColor());
            }
            UserVO creatorUser = paasProcessNodeTaskVO.getCreatorUser();
            if (creatorUser == null) {
                summaryDataVO.setTitle("***"+ I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName());
            } else {
                summaryDataVO.setTitle(creatorUser.getName() + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName());
            }
            summaryDataVO.setProcessNodeTask(paasProcessNodeTaskVO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("summaryItem数据库出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return summaryDataVO;
    }

    @Override
    public ProcessNodeTaskCountVO count(ProcessNodeTaskCountDTO processNodeTaskCountDTO) throws XbbException {
        ProcessNodeTaskCountVO processNodeTaskCountVO = new ProcessNodeTaskCountVO();
        String corpid = processNodeTaskCountDTO.getCorpid();
        String userId = processNodeTaskCountDTO.getUserId();
        try {
            // 提交给我的 待审批的
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(StringConstant.CORPID, corpid);
            params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            params.put("taskType", TaskTypeEnum.UNTREATED.getType());
            params.put("userId", userId);
            params.put("nodeType", NodeTypeEnum.PROCESS_NODE.getNodeType());
            Integer todo = paasProcessNodeTaskModel.getTaskCountLimit(params);
            processNodeTaskCountVO.setTodo(todo);
            // 抄送我的
            params.remove("nodeType");
            params.put("taskType", TaskTypeEnum.CC.getType());
            params.put("isRead", 0);
            Integer cc = paasProcessNodeTaskModel.getTaskCountLimit(params);
            processNodeTaskCountVO.setCc(cc);
            // 我提交的
            params.remove("userId");
            params.put("creatorId", processNodeTaskCountDTO.getUserId());
            params.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            params.put("taskType", TaskTypeEnum.COMMIT.getType());
            params.put("isRead", 0);
            Integer create = paasProcessNodeTaskModel.getTaskCountLimit(params);
            processNodeTaskCountVO.setCreate(create);
        } catch (Exception e) {
            LOG.error("mobilePaasProcessTask数据库获取卡片列表出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskCountVO;
    }

    @Override
    public ProcessNodeTaskShowVO show(ProcessNodeTaskCountDTO processNodeTaskCountDTO) throws XbbException {
        ProcessNodeTaskShowVO processNodeTaskShowVO = new ProcessNodeTaskShowVO();
        String corpid = processNodeTaskCountDTO.getCorpid();
        String userId = processNodeTaskCountDTO.getUserId();
        try {
            List<ProcessNodeTaskPojo> processNodeTaskPojoList = new ArrayList<>();
            Set<String> permSet = processNodeTaskCountDTO.getLoginUser().getPermSet();
            if (permSet.contains(ProPermissionAliasEnum.PROCESS_VIEW.getAlias())) {
                // 提交给我的 待审批的
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put(StringConstant.CORPID, corpid);
                params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                params.put("taskType", TaskTypeEnum.UNTREATED.getType());
                params.put("userId", userId);
                params.put("nodeType", NodeTypeEnum.PROCESS_NODE.getNodeType());
                Integer todo = paasProcessNodeTaskModel.getTaskCountLimit(params);
                ProcessNodeTaskPojo todoPojo = new ProcessNodeTaskPojo();
                todoPojo.setAlias("todo");
                todoPojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.SUBMIT_TO_ME));
                todoPojo.setIcon("app-icon-tijiaowode");
                todoPojo.setValue(todo);
                processNodeTaskPojoList.add(todoPojo);
                // 抄送我的
                params.remove("nodeType");
                params.put("taskType", TaskTypeEnum.CC.getType());
                params.put("isRead", 0);
                Integer cc = paasProcessNodeTaskModel.getTaskCountLimit(params);
                ProcessNodeTaskPojo ccPojo = new ProcessNodeTaskPojo();
                ccPojo.setAlias("cc");
                ccPojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.COPY_ME));
                ccPojo.setIcon("app-icon-chaosongwode");
                ccPojo.setValue(cc);
                processNodeTaskPojoList.add(ccPojo);
                // 我提交的
                params.remove("userId");
                params.put("creatorId", processNodeTaskCountDTO.getUserId());
                params.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
                params.put("taskType", TaskTypeEnum.COMMIT.getType());
                params.put("isRead", 0);
                Integer create = paasProcessNodeTaskModel.getTaskCountLimit(params);
                ProcessNodeTaskPojo creatPojo = new ProcessNodeTaskPojo();
                creatPojo.setAlias("create");
                creatPojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.MY_SUBMITTED));
                creatPojo.setIcon("app-icon-wotijiaode");
                creatPojo.setValue(create);
                processNodeTaskPojoList.add(creatPojo);
            }

            if (permSet.contains(ProPermissionAliasEnum.CHART_VIEW.getAlias())) {
                ProcessNodeTaskPojo chartPojo = new ProcessNodeTaskPojo();
                chartPojo.setAlias("chart");
                chartPojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.CHART_CENTER));
                chartPojo.setIcon("app-icon-tubiaozhongxin");
                chartPojo.setValue(0);
                processNodeTaskPojoList.add(chartPojo);
            }
            processNodeTaskShowVO.setProcessNodeTaskPojoList(processNodeTaskPojoList);
        } catch (Exception e) {
            LOG.error("mobilePaasProcessTask数据库获取卡片列表出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskShowVO;
    }

    @Override
    public BaseVO readNode(ProcessNodeTaskReadDTO processNodeTaskReadDTO) throws XbbException {
        PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = paasProcessNodeTaskModel.getByKey(processNodeTaskReadDTO.getNodeTaskId().intValue(), processNodeTaskReadDTO.getCorpid());
        if (paasProcessNodeTaskEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
        }
        paasProcessNodeTaskEntity.setIsRead(1);
        paasProcessNodeTaskModel.readStartNode(paasProcessNodeTaskEntity);
        return new BaseVO();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseVO delTask(ProcessTaskDelDTO processTaskDelDTO) throws XbbException {
        // 判断是否有删除流程的权限
        Set<String> permSet = processTaskDelDTO.getLoginUser().getPermSet();
        if (!permSet.contains(ProPermissionAliasEnum.PROCESS_DELETE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.PROCESS_DELETE.getMemo()));
        }
        PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(processTaskDelDTO.getTaskId().intValue(), processTaskDelDTO.getCorpid());
        PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(processTaskDelDTO.getTaskId(), processTaskDelDTO.getCorpid());
        if (paasProcessTaskEntity == null || paasProcessDataEntity == null) {
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209002, ApprovalErrorCodeEnum.API_ERROR_209002.getMsg());
        }
        String corpid = processTaskDelDTO.getCorpid();
        PaasProcessTemplateEntityExt processTemplateEntityExt = paasProcessTemplateModel.getByKey(paasProcessTaskEntity.getTemplateId(), corpid);
        Integer businessType = paasProcessTaskEntity.getBusinessType();
        PaasFormEntity paasFormEntityExt = proFormHelp.getPaasForm(processTemplateEntityExt.getFormId(), paasProcessTaskEntity.getBusinessType(), corpid);
        // 经销商资金相关的审批不允许删除
        List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.INVOICE.getCode(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getCode(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getCode());
        if (Objects.nonNull(paasFormEntityExt) && Objects.equals(paasFormEntityExt.getDistributorMark(), 1) && businessTypeList.contains(paasFormEntityExt.getBusinessType())) {
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209016);
        }
        paasProcessTaskModel.delete(paasProcessTaskEntity);
        paasProcessDataModel.deleteByTaskId(paasProcessTaskEntity.getId(), processTaskDelDTO.getCorpid());
        paasProcessNodeTaskModel.deleteByTaskId(paasProcessTaskEntity.getId(), processTaskDelDTO.getCorpid());
        paasProcessRelatedDataModel.deleteByTaskId(paasProcessTaskEntity.getId(), processTaskDelDTO.getCorpid());
        if ((Objects.equals(paasProcessDataEntity.getFlowStatus(), FlowStatusEnum.IN_APPROVAL.getType()) || Objects.equals(paasProcessDataEntity.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType()))) {
            if(!Objects.equals(paasProcessDataEntity.getFormDataId(), 0L)) {
            /*if (Objects.equals(paasProcessDataEntity.getPostPosition(), 1)) {
                // TODO 回退业务数据
                FormDataDeleteBatchDTO formDataDeleteBatchDTO = new FormDataDeleteBatchDTO();
                BeanUtil.copyProperties(processTaskDelDTO, formDataDeleteBatchDTO);
                formDataDeleteBatchDTO.setAppId(paasProcessDataEntity.getAppId());
                formDataDeleteBatchDTO.setMenuId(paasProcessDataEntity.getMenuId());
                formDataDeleteBatchDTO.setFormId(paasProcessDataEntity.getFormId());
                formDataDeleteBatchDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formDataDeleteBatchDTO.setBusinessType(paasProcessDataEntity.getBusinessType());
                formDataDeleteBatchDTO.setDataIdList(Collections.singletonList(paasProcessDataEntity.getFormDataId()));
                formDataDeleteBatchDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
                formDataDeleteBatchDTO.setFromProcess(1);
                listBatchService.deleteBySingle(formDataDeleteBatchDTO);
            } else {*/
                proModelService.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.PASS.getType());
                //}
            }
        }
        // 删除时同步删除钉钉待办实例
        String dingtalkProcessInstanceId = paasProcessTaskEntity.getDingtalkProcessInstanceId();
        if (StringUtil.isNotEmpty(dingtalkProcessInstanceId)) {
            workflowDingtalkService.updateDingtalkInstance(paasProcessTaskEntity.getCorpid(), dingtalkProcessInstanceId, WorkrecordResultEnum.TERMINATED);
        }

        //操作日志
        UserVO loginUser = processTaskDelDTO.getLoginUser();
        List<UserEntity> userList = userModel.getByUserId(Collections.singletonList(paasProcessTaskEntity.getCreatorId()), corpid);
        String title;
        if (CollectionUtils.isEmpty(userList)) {
            title = "***"+ I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL);
        } else {
            title = userList.get(0).getName() + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL);
        }
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DEL_WORKFLOW_TASK),loginUser.getName(),title);
        DetailLogPojo detailLogPojo = new DetailLogPojo();
        detailLogPojo.setFromWorkflowOrApproval(paasFormEntityExt.getName());
        detailLogPojo.setTriggerForm(paasFormEntityExt.getName());
        String versionName = processTemplateEntityExt.getVersionName();
        versionName = StringUtils.isEmpty(versionName) ? "v1" : versionName;
        detailLogPojo.setWorkflowVersion(versionName);
        mongoLogHelp.buildLog4DetailArrWithComplexDetail(Collections.singletonList(detailLogPojo),corpid,loginUser.getUserId(),loginUser.getName(), OperateModuleTypeEnum.APPROVAL, OperateTypeEnum.APPROVAL_DEL,paasFormEntityExt.getId().toString(),title,memo,processTaskDelDTO.getHttpHeader(),BasicConstant.FOUR);

        return new BaseVO();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ProcessNodeTaskUpdateVO adminTransfer(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) throws XbbException {
        ProcessNodeTaskUpdateVO processNodeTaskUpdateVO;
        // 移除data里面的创建人和创建时间，这两个属性是放在data外面的
        if (processNodeTaskUpdateDTO.getDataList() != null) {
            processNodeTaskUpdateDTO.getDataList().remove("creatorId");
            processNodeTaskUpdateDTO.getDataList().remove("addTime");
        }
        String hashKey = processNodeTaskUpdateDTO.getCorpid() + "_" + processNodeTaskUpdateDTO.getUserId() + "_" + processNodeTaskUpdateDTO.getProcessNodeTaskId();
        if (Objects.nonNull(paasRedisHelper.getValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey))) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_IS_DEAL);
        }
        try {
            paasRedisHelper.setValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey,true, RedisConstant.MICRO_DURATION);
            // 当前审批类型 提交 暂存 拒绝 转交等
            Integer taskType = processNodeTaskUpdateDTO.getTaskType();
            TaskTypeEnum taskTypeEnum = TaskTypeEnum.getTaskTypeEnum(taskType);
            if (!Objects.equals(TaskTypeEnum.TRANSFER, taskTypeEnum)) {
               throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200028);
            }
            // 获取当前审批节点
            PaasProcessNodeTaskEntity entity = paasProcessNodeTaskModel.getByKey(processNodeTaskUpdateDTO.getProcessNodeTaskId().intValue(), processNodeTaskUpdateDTO.getCorpid());
            if (entity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            // 防止多次提交
//            if ((!Objects.equals(entity.getTaskType(), TaskTypeEnum.UNTREATED.getType()) && !Objects.equals(entity.getNodeType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType()))
//                    || Objects.equals(taskType, entity.getTaskType())) {
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_HAVE_DEAL);
//            }
            processNodeTaskUpdateDTO.setPaasProcessNodeTaskEntity(entity);
            // 查询任务所在当前节点模板信息
            PaasProcessTemplateNodeEntityExt processTemplateNodeEntity = processTemplateNodeModel.getByKey(entity.getTemplateNodeId().intValue(), processNodeTaskUpdateDTO.getCorpid());
            if (processTemplateNodeEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            processNodeTaskUpdateDTO.setProcessTemplateNode(processTemplateNodeEntity);

            // 获取之前的流程数据
            PaasProcessDataEntity processDataEntity = paasProcessDataModel.getByTaskId(processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getCorpid());
            if (Objects.isNull(processDataEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_DATA_NOT_EXIST);
            }

            //在此处就提前获取，防止在内部方法被置入了新的data
            if (Objects.nonNull(processNodeTaskUpdateDTO.getOwnerId()) && !processNodeTaskUpdateDTO.getOwnerId().isEmpty()) {
                processDataEntity.setOwnerId(Objects.toString(processNodeTaskUpdateDTO.getOwnerId().get(0).getId(), ""));
            }

            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = JsonHelperUtil.parseObject(processDataEntity.getSaasNeedPoJo(), SaasNeedRedundantAttrPojo.class);
            saasNeedRedundantAttrPojo = saasNeedRedundantAttrPojo == null ? new SaasNeedRedundantAttrPojo() : saasNeedRedundantAttrPojo;
            processNodeTaskUpdateDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            processNodeTaskUpdateDTO.setDepartmentId(processDataEntity.getDepartmentId());

            Integer opinionFlag = processTemplateNodeEntity.getOpinionFlag();
            String opinion = processNodeTaskUpdateDTO.getOpinion();
            // 审批意见必填时过滤暂存撤回操作
            if (Objects.equals(opinionFlag, ProcessOpinionEnum.REQUIRED.getValue()) && StringUtil.isEmpty(opinion, true)
                    && !Objects.equals(taskTypeEnum, TaskTypeEnum.STORAGE) && !Objects.equals(taskTypeEnum, TaskTypeEnum.REVOKE)
                    && !Objects.equals(taskTypeEnum, TaskTypeEnum.AGAIN_COMMIT) && !Objects.equals(taskTypeEnum, TaskTypeEnum.TRANSFER)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.APPROVE_OPINION_REQUIRED);
            }

            // 将审批意见等信息存储，更新当前任务的状态
            PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = new PaasProcessNodeTaskEntity();
            BeanUtils.copyProperties(processNodeTaskUpdateDTO, paasProcessNodeTaskEntity);
            paasProcessNodeTaskEntity.setId(processNodeTaskUpdateDTO.getProcessNodeTaskId());
            // 暂存时，不处理当前任务的状态
            if (!(Objects.equals(taskType, TaskTypeEnum.STORAGE.getType()) || Objects.equals(taskType, TaskTypeEnum.REVOKE.getType()))) {
                // 审批图片，附件等
                if (processNodeTaskUpdateDTO.getImages() != null && !processNodeTaskUpdateDTO.getImages().isEmpty()) {
                    paasProcessNodeTaskEntity.setImages(JSONObject.toJSONString(processNodeTaskUpdateDTO.getImages()));
                }
                if (processNodeTaskUpdateDTO.getAttachmentList() != null && !processNodeTaskUpdateDTO.getAttachmentList().isEmpty()) {
                    paasProcessNodeTaskEntity.setAttachment(JSONObject.toJSONString(processNodeTaskUpdateDTO.getAttachmentList()));
                }

                paasProcessNodeTaskModel.update(paasProcessNodeTaskEntity);

            }
            if (processNodeTaskUpdateDTO.getAtUserIds() != null && !processNodeTaskUpdateDTO.getAtUserIds().isEmpty()) {
                paasCommentService.pushProcessComment(processNodeTaskUpdateDTO.getLoginUser(), processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getAtUserIds());
            }
            // 流程操作
            processNodeTaskUpdateVO = dingOperateProcessNodeTask(taskTypeEnum, processNodeTaskUpdateDTO);
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
            // 更新酷应用卡片
            updateCoolCard(processNodeTaskUpdateDTO);
        } catch (XbbException e) {
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库流程操作出错", e);
            paasRedisHelper.removeValue(RedisPrefixConstant.PROCESS_NODE_TASK,hashKey);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return processNodeTaskUpdateVO;
    }

    private ProcessNodeTaskUpdateVO dingOperateProcessNodeTask(TaskTypeEnum taskTypeEnum, ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) throws XbbException {
        ProcessNodeTaskUpdateVO processNodeTaskUpdateVO = new ProcessNodeTaskUpdateVO();
        try {
            switch (taskTypeEnum) {
                case COMMIT:
                    // 提交操作
                    processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.dingCommit(processNodeTaskUpdateDTO);
                    break;
                case STORAGE:
                    // 暂存 只修改数据，不修改流程状态
                    processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.storage(processNodeTaskUpdateDTO);
                    break;
                case TRANSFER:
                    // 转交
                    processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.transfer(processNodeTaskUpdateDTO);
                    break;
                case BACK:
                    // 回退
                    processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.dingBack(processNodeTaskUpdateDTO);
                    break;
                case REVOKE:
                    // 撤回
                    processNodeTaskUpdateVO = paasProcessNodeTaskOperateService.revoke(processNodeTaskUpdateDTO);
                    break;
                case END:
                    // 结束流程/拒绝流程
                    paasProcessNodeTaskOperateService.end(processNodeTaskUpdateDTO);
                    break;
                case AGAIN_COMMIT:
                    // 重新提交
                    paasProcessNodeTaskOperateService.dingAgainCommit(processNodeTaskUpdateDTO);
                    break;
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, SystemErrorCodeEnum.API_ERROR_100028.getMsg());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask流程节点操作出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskUpdateVO;
    }

    /**
     * 获取流程操作
     *
     * @param templateNode
     * @param processNodeTaskGetDTO
     * @param openWorkFlow
     * @return
     * @throws XbbException
     */
    private void getProcessOperator(PaasProcessTemplateNodeEntityExt templateNode, ProcessNodeTaskGetDTO processNodeTaskGetDTO,
                                    ProcessNodeTaskGetVO processNodeTaskGetVO, PaasProcessTemplateEntity processTemplate,
                                    PaasProcessNodeTaskEntity paasProcessNodeTaskEntity, Map<String, UserEntity> userMap, boolean openWorkFlow) throws XbbException {
        List<ProcessOperateVo> resultList = new ArrayList<>();
        ProcessTemplateNodeVO processOperatePermission = new ProcessTemplateNodeVO();
        try {
            if (commonHelp.isOpenWorkFlow(processNodeTaskGetDTO.getCorpid())) {
                ProcessTemplateNodeVO processTemplateNodeVO = new ProcessTemplateNodeVO();
                processNodeTaskGetVO.setProcessOperatePermission(processTemplateNodeVO);
                return;
            }

            if (Objects.equals(paasProcessNodeTaskEntity.getUserId(), processNodeTaskGetDTO.getLoginUser().getUserId())) {

                boolean unRevokeFlag = !Objects.equals(templateNode.getType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType())
                        && Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.TODO.getValue());
                // 允许提交且不是撤回的流程
                boolean commitFlag = templateNode.getCommitFlag().equals(1) && unRevokeFlag;

                if (commitFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(templateNode.getCommitText());
                    operatePoJo.setFlag(templateNode.getCommitFlag());
                    operatePoJo.setType(TaskTypeEnum.COMMIT.getType());
                    resultList.add(operatePoJo);
                }
                // 允许结束且不是撤回的流程
                boolean endFlag = templateNode.getEndFlag().equals(1) && unRevokeFlag;
                if (endFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(templateNode.getEndText());
                    operatePoJo.setFlag(templateNode.getEndFlag());
                    operatePoJo.setType(TaskTypeEnum.END.getType());
                    resultList.add(operatePoJo);
                }
                // 允许暂存且不是撤回的流程
                boolean storageFlag = templateNode.getStorageFlag().equals(1) && unRevokeFlag;
                if (storageFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(templateNode.getStorageText());
                    operatePoJo.setFlag(templateNode.getStorageFlag());
                    operatePoJo.setType(TaskTypeEnum.STORAGE.getType());
                    resultList.add(operatePoJo);
                }
                // 允许回退且不是撤回的流程
                boolean backFlag = templateNode.getBackFlag().equals(1) && unRevokeFlag;
                if (backFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(templateNode.getBackText());
                    operatePoJo.setFlag(templateNode.getBackFlag());
                    operatePoJo.setType(TaskTypeEnum.BACK.getType());
                    resultList.add(operatePoJo);
                }
                // 允许转交且不是撤回的流程
                boolean transferFlag = templateNode.getTransferFlag().equals(1) && unRevokeFlag;
                if (transferFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(templateNode.getTransferText());
                    operatePoJo.setFlag(templateNode.getTransferFlag());
                    operatePoJo.setType(TaskTypeEnum.TRANSFER.getType());
                    resultList.add(operatePoJo);
                    if (!templateNode.getTransferUserList().isEmpty()) {
                        List<UserVO> transferUserList = userInfoHelp.getUserList(templateNode.getTransferUserList(), processNodeTaskGetDTO);
                        for (UserVO user : transferUserList) {
                            if (Objects.equals(user.getDel(), DelEnum.DELETE.getDel())) {
                                String name = user.getName();
                                user.setName(name + "(" + I18nMessageUtil.getMessage(CommonConstant.LEAVE) + ")");
                            }
                        }
                        processOperatePermission.setTransferUserList(transferUserList);
                    }
                }
                // 允许撤回，流程状态为待审批，当前用户为创建人，当前列表是我提交的 显示撤回按钮
                boolean revokeFlag = Objects.equals(processTemplate.getAllowWithdraw(), 1)
                        && Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType())
                        && processNodeTaskGetVO.getCommitUser().getUserId().equals(processNodeTaskGetDTO.getUserId())
                        && Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.CREATE.getValue());
                if (revokeFlag) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(TaskTypeEnum.REVOKE.getMemo());
                    operatePoJo.setFlag(1);
                    operatePoJo.setType(TaskTypeEnum.REVOKE.getType());
                    resultList.add(operatePoJo);
                }
                // 流程被拒绝 || 被撤回的流程 当前用户为创建人 显示重新提交
                boolean againFlag = (Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.REJECT.getType())
                        || Objects.equals(processNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.REVOKE.getType())
                        && Objects.equals(processNodeTaskGetVO.getCommitUser().getUserId(), processNodeTaskGetDTO.getUserId()))
                        && Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.CREATE.getValue());
                if (againFlag && Objects.equals(processNodeTaskGetVO.getDataId(), 0L)) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(TaskTypeEnum.AGAIN_COMMIT.getMemo());
                    operatePoJo.setFlag(1);
                    operatePoJo.setType(TaskTypeEnum.AGAIN_COMMIT.getType());
                    resultList.add(operatePoJo);
                }

            }

            //　系统提交
            boolean systemCommit = Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.ALL.getValue())
                    && Objects.equals(paasProcessNodeTaskEntity.getUserId(), PaasConstant.SYS_USER_ID)
                    && !Objects.equals(templateNode.getType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType());
            // 离职人员需要转交按钮
            boolean isDismiss = Objects.equals(processNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.ALL.getValue()) && (!userMap.containsKey(paasProcessNodeTaskEntity.getUserId()) || Objects.equals(userMap.get(paasProcessNodeTaskEntity.getUserId()).getDel(), 1));
            if(systemCommit || isDismiss) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setText(TaskTypeEnum.SYSTEM_COMMIT.getMemo());
                operatePoJo.setFlag(1);
                operatePoJo.setType(TaskTypeEnum.SYSTEM_COMMIT.getType());
                resultList.add(operatePoJo);
            }

            processOperatePermission.setOpinionFlag(templateNode.getOpinionFlag());
            processOperatePermission.setBackType(templateNode.getBackType());
            processOperatePermission.setProcessOperate(resultList);
            processNodeTaskGetVO.setProcessOperatePermission(processOperatePermission);
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取流程操作权限出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 获取流程节点任务日志
     *
     * @param nodeTaskList         节点任务
     * @param userMap              用户容器
     * @param processNodeTaskGetVO 返回数据封装
     * @throws XbbException
     */
    private void getProcessNodeTaskLogList(List<PaasProcessNodeTaskEntityExt> nodeTaskList, Map<String, UserEntity> userMap,
                                           ProcessNodeTaskGetVO processNodeTaskGetVO, ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        try {
            List<Object> historyLogList = new ArrayList<>();
            List<Object> currentLogList = new ArrayList<>();
            Map<String, Object> params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
            // 流程模板删除后需要继续流转之前的流程 有流程流转时不允许关闭模板
            params.remove("del");
            //这边去掉业务类型，有个入口自定义表单的task给了businesstype为4，没找到入口，现在这边去掉业务类型，防止recors获取失败
            params.remove(ParameterConstant.BUSINESS_TYPE);
            params.put(ParameterConstant.COLUMNS, "allow_view_log");
            // TODO BUG 这个模板可能不是当前流转的模板
            List<PaasProcessTemplateEntityExt> processTemplateList = paasProcessTemplateModel.list(params);
            // 当前节点任务
            PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = null;
            for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : nodeTaskList) {
                if (Objects.equals(paasProcessNodeTaskEntityExt.getId(), processNodeTaskGetDTO.getProcessNodeTaskId())) {
                    paasProcessNodeTaskEntity = paasProcessNodeTaskEntityExt;
                    break;
                }
            }
            if (Objects.isNull(paasProcessNodeTaskEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }
            if (processTemplateList == null || processTemplateList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TEMPLATE_NOT_EXIST);
            }
            PaasProcessTemplateEntityExt paasProcessTemplateEntityExt = processTemplateList.get(0);

            Integer allowViewLog = paasProcessTemplateEntityExt.getAllowViewLog();
            CommentListDTO commentListDTO = new CommentListDTO();
            BeanUtil.copyProperties(processNodeTaskGetDTO, commentListDTO);
            commentListDTO.setRefId(processNodeTaskGetDTO.getProcessTaskId());
            // 审批评论类型
            commentListDTO.setBusinessType(BusinessCommentEnum.APPROVAL.getBusinessType());
            // TODO 暂时置成null值，因为后面会有获取根据类型获取评论
            commentListDTO.setSaasMark(null);
            CommentListVO commentListVO = paasCommentService.list(commentListDTO);
            if (commentListVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasCommentEntityExt> commentList = commentListVO.getList();
            Set<String> userIdSet = new HashSet<>();
            if (CollectionsUtil.isNotEmpty(nodeTaskList)) {
                PaasProcessNodeTaskEntityExt createNodeTask = new PaasProcessNodeTaskEntityExt();
                for (PaasProcessNodeTaskEntityExt item : nodeTaskList) {
                    if ((item.getTaskType().equals(TaskTypeEnum.COMMIT.getType()) || item.getTaskType().equals(TaskTypeEnum.REVOKE.getType())) && NodeTypeEnum.START_PROCESS_NODE.getNodeType().equals(item.getNodeType())) {
                        // 这里的任务是重新提交的开始节点
                        createNodeTask = item;
                    }
                }

                List<ProcessNodeTaskLogPoJo> historyUnSubmitNodeTask = new ArrayList<>();
                List<ProcessNodeTaskLogPoJo> currentUnSubmitNodeTask = new ArrayList<>();
                List<UserEntity> ccUserList = new ArrayList<>();
                Set<Long> templateIdList = new HashSet<>();
                for (PaasProcessNodeTaskEntityExt item : nodeTaskList) {
                    // 获取节点模板id
                    templateIdList.add(item.getTemplateNodeId());

                    // 过滤其他人同意的节点任务
                    if (item.getTaskType().equals(TaskTypeEnum.OTHER_COMMIT.getType())) {
                        continue;
                    }
                    // 当前节点的抄送人
                    if (item.getTemplateNodeId().equals(paasProcessNodeTaskEntity.getTemplateNodeId()) &&
                            (item.getTaskType().equals(TaskTypeEnum.WAIT_CC.getType()) || item.getTaskType().equals(TaskTypeEnum.CC.getType()))  &&
                            item.getAddTime() >= createNodeTask.getUpdateTime()
                            ) {
                        // 抄送人
                        if (userMap.containsKey(item.getUserId())) {
                            ccUserList.add(userMap.get(item.getUserId()));
                        }
//                        continue;
                    } else if (item.getTaskType().equals(TaskTypeEnum.WAIT_CC.getType())) {
                        continue;
                    }
                    ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = getProcessNodeTaskLog(item, userMap, processNodeTaskGetDTO);
                    if (createNodeTask.getAddTime() != null && createNodeTask.getAddTime() > item.getAddTime()) {
                        // 历史审批记录
                        if (item.getTaskType().equals(TaskTypeEnum.UNTREATED.getType())) {
                            historyUnSubmitNodeTask.add(processNodeTaskLogPoJo);
                        } else {
                            historyLogList.add(processNodeTaskLogPoJo);
                        }
                    } else {
                        // 当前审批记录
                        if (item.getTaskType().equals(TaskTypeEnum.UNTREATED.getType())) {
                            if (Objects.isNull(processNodeTaskLogPoJo.getOperatorUser())) {
                                continue;
                            }
                            if (userIdSet.contains(processNodeTaskLogPoJo.getOperatorUser().getUserId())) {
                                currentUnSubmitNodeTask.removeIf(processNodeTask -> Objects.equals(processNodeTask.getOperatorUser().getUserId(), processNodeTaskLogPoJo.getOperatorUser().getUserId()));
                            }
                            userIdSet.add(processNodeTaskLogPoJo.getOperatorUser().getUserId());
                            currentUnSubmitNodeTask.add(processNodeTaskLogPoJo);
                        } else {
                            currentLogList.add(processNodeTaskLogPoJo);
                        }
                    }
                }
                processNodeTaskGetVO.setCcUserList(ccUserList);

                // 查询所有节点
                params.put("idIn", templateIdList);
                List<PaasProcessTemplateNodeEntityExt> paasProcessTemplateNodeEntityExts = processTemplateNodeModel.list(params);
                if (Objects.isNull(paasProcessTemplateNodeEntityExts)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
                }
                Map<Long, PaasProcessTemplateNodeEntityExt> paasProcessTemplateNodeEntityExtMap = new HashMap<>(paasProcessTemplateNodeEntityExts.size());
                paasProcessTemplateNodeEntityExts.forEach(item -> paasProcessTemplateNodeEntityExtMap.put(item.getId(), item));

                // 判断流程状态的最后一个
                if (!historyLogList.isEmpty()) {
                    // 获取最后一个节点任务
                    getUnCommitNodeTaskList(historyLogList, historyUnSubmitNodeTask);
                    // 增加节点名称
                    addTemplateNodeName(historyLogList, paasProcessTemplateNodeEntityExtMap);
                }
                if (!currentLogList.isEmpty()) {
                    getUnCommitNodeTaskList(currentLogList, currentUnSubmitNodeTask);
                    addTemplateNodeName(currentLogList, paasProcessTemplateNodeEntityExtMap);
                }
                if (commentList != null && !commentList.isEmpty()) {
                    for (PaasCommentEntityExt item : commentList) {
                        if (Objects.equals(item.getUserId(), processNodeTaskGetDTO.getUserId())) {
                            item.setUserName(I18nMessageUtil.getMessage(CommonConstant.ME));
                        }
                        if (createNodeTask.getAddTime() != null && createNodeTask.getAddTime() > item.getAddTime()) {
                            // 历史审批记录
                            historyLogList.add(item);
                        } else {
                            // 当前审批记录
                            currentLogList.add(item);
                        }
                    }
                }
            }
            if (!currentLogList.isEmpty()) {
                bubbleSort(currentLogList);
                sortUntreatedObject(currentLogList);
            }
            processNodeTaskGetVO.setCurrentLog(currentLogList);
            if (allowViewLog.equals(1)) {
                if (!historyLogList.isEmpty()) {
                    bubbleSort(historyLogList);
                    sortUntreatedObject(historyLogList);
                }
                processNodeTaskGetVO.setHistoryLog(historyLogList);
            } else {
                processNodeTaskGetVO.setHistoryLog(new ArrayList<>());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取流程日志出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 强行将未处理的节点放到最后
     * @param currentLogList
     */
    private void sortUntreatedObject(List<Object> currentLogList) {
        List<Object> untreatedList = new ArrayList<>();
        Iterator<Object> iterator = currentLogList.iterator();
        while (iterator.hasNext()) {
            Object object = iterator.next();
            if (object instanceof ProcessNodeTaskLogPoJo) {
                ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) object;
                if (Objects.equals(processNodeTaskLogPoJo.getTaskType(), TaskTypeEnum.UNTREATED.getType())) {
                    untreatedList.add(object);
                    iterator.remove();
                }
            }
        }
        currentLogList.addAll(untreatedList);
    }

    /**
     * 获取没有提交的节点任务列表
     *
     * @param logList                 历史日志和当前审批
     * @param counterSignNodeTaskList 会签或或签的没有提交的任务节点
     */
    private void getUnCommitNodeTaskList(List<Object> logList, List<ProcessNodeTaskLogPoJo> counterSignNodeTaskList) {
        ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) logList.get(logList.size() - 1);
        if (!counterSignNodeTaskList.isEmpty()
                && processNodeTaskLogPoJo.getTemplateNodeId().equals(counterSignNodeTaskList.get(0).getTemplateNodeId())
                && processNodeTaskLogPoJo.getNodeType().equals(TaskTypeEnum.CC.getType())) {
            processNodeTaskLogPoJo.setUnCommitNodeTaskList(counterSignNodeTaskList);
            logList.set(logList.size() - 1, processNodeTaskLogPoJo);
        } else if (!counterSignNodeTaskList.isEmpty()) {
            ProcessNodeTaskLogPoJo unCommitNodeTask = counterSignNodeTaskList.get(counterSignNodeTaskList.size()-1);
            ProcessNodeTaskLogPoJo lastNodeTask = new ProcessNodeTaskLogPoJo();
            lastNodeTask.setId(unCommitNodeTask.getId());
            lastNodeTask.setSignType(unCommitNodeTask.getSignType());
            lastNodeTask.setSignTypeDesc(SignTypeEnum.getSignTypeEnum(unCommitNodeTask.getSignType()));
            lastNodeTask.setNodeType(unCommitNodeTask.getNodeType());
            lastNodeTask.setCounterSignUnFinish(1);
            lastNodeTask.setTaskType(unCommitNodeTask.getTaskType());
            lastNodeTask.setAddTime(unCommitNodeTask.getAddTime());
            lastNodeTask.setUpdateTime(unCommitNodeTask.getUpdateTime());
            lastNodeTask.setUnCommitNodeTaskList(counterSignNodeTaskList);
            logList.add(lastNodeTask);
            /*Map<Long, List<ProcessNodeTaskLogPoJo>> ret = getListGroup(counterSignNodeTaskList);
            for (Map.Entry<Long, List<ProcessNodeTaskLogPoJo>> entry : ret.entrySet()){
                List<ProcessNodeTaskLogPoJo> list = entry.getValue();
                ProcessNodeTaskLogPoJo unCommitNodeTask = list.get(0);
                ProcessNodeTaskLogPoJo lastNodeTask = new ProcessNodeTaskLogPoJo();
                lastNodeTask.setId(unCommitNodeTask.getId());
                lastNodeTask.setSignType(unCommitNodeTask.getSignType());
                lastNodeTask.setSignTypeDesc(SignTypeEnum.getSignTypeEnum(unCommitNodeTask.getSignType()));
                lastNodeTask.setNodeType(unCommitNodeTask.getNodeType());
                lastNodeTask.setCounterSignUnFinish(1);
                lastNodeTask.setTaskType(unCommitNodeTask.getTaskType());
                lastNodeTask.setAddTime(unCommitNodeTask.getAddTime());
                lastNodeTask.setUpdateTime(unCommitNodeTask.getUpdateTime());
                lastNodeTask.setUnCommitNodeTaskList(list);
                logList.add(lastNodeTask);
            }*/
        }
    }

    /**
     * 为审批节点分组
     *
     * @param logList
     * @return
     */
    private static Map<Long, List<ProcessNodeTaskLogPoJo>> getListGroup(List<ProcessNodeTaskLogPoJo> logList) {
        Map<Long, List<ProcessNodeTaskLogPoJo>> ret = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //同名的分为一组
        for (ProcessNodeTaskLogPoJo processNodeTaskLogPoJo : logList) {
            //如果不存在实体字段的键，则创建一个list，并将list添加至map
            if (!ret.containsKey(processNodeTaskLogPoJo.getAddTime())) {
                ArrayList<ProcessNodeTaskLogPoJo> li = new ArrayList<>();
                li.add(processNodeTaskLogPoJo);
                ret.put(processNodeTaskLogPoJo.getAddTime(), li);
            } else {
                //如果存在，则直接在list中添加一个即可
                ret.get(processNodeTaskLogPoJo.getAddTime()).add(processNodeTaskLogPoJo);
            }
        }
        return ret;
    }

    /**
     * 冒泡排序  按照时间排序，如果时间一样，按照id排序
     *
     * @param list
     */
    private static void bubbleSort(List<Object> list) {
        int len = list.size();
        for (int i = 0; i < len - 1; i++) {
            for (int j = 0; j < len - 1 - i; j++) {
                long addTimeLeft = 0L;
                long addTimeMid = 0L;
                long idLeft = 0L;
                long idMid = 0L;
                //long typeLeft = 0L;
                //long typeMid = 0L;
                if (list.get(j) instanceof ProcessNodeTaskLogPoJo) {
                    ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) list.get(j);
                    addTimeLeft = processNodeTaskLogPoJo.getUpdateTime();
                    idLeft = processNodeTaskLogPoJo.getId();
                }
                if (list.get(j) instanceof PaasCommentEntityExt) {
                    PaasCommentEntityExt paasCommentEntityExt = (PaasCommentEntityExt) list.get(j);
                    addTimeLeft = paasCommentEntityExt.getUpdateTime();
                    idLeft = paasCommentEntityExt.getId();
                }
                if (list.get(j + 1) instanceof ProcessNodeTaskLogPoJo) {
                    ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) list.get(j + 1);
                    addTimeMid = processNodeTaskLogPoJo.getUpdateTime();
                    idMid = processNodeTaskLogPoJo.getId();
                }
                if (list.get(j + 1) instanceof PaasCommentEntityExt) {
                    PaasCommentEntityExt paasCommentEntityExt = (PaasCommentEntityExt) list.get(j + 1);
                    addTimeMid = paasCommentEntityExt.getUpdateTime();
                    idMid = paasCommentEntityExt.getId();
                }
                // 相邻元素两两对比
                if (addTimeLeft == addTimeMid) {
                    //if(typeLeft == typeMid){
                    if (idLeft > idMid) {
                        elementExchange(j, list);
                    }
                    //}else if(typeLeft < typeMid){
                    //elementExchange(j, list);
                    //}
                } else if (addTimeLeft > addTimeMid) {
                    elementExchange(j, list);
                }
            }
        }
    }

    private static void elementExchange(int j, List<Object> list) {
        // 元素交换
        Object temp = list.get(j + 1);
        list.set(j + 1, list.get(j));
        list.set(j, temp);
    }

    /**
     * 封装流程日志对象
     *
     * @param item
     * @param userMap
     * @return
     */
    private ProcessNodeTaskLogPoJo getProcessNodeTaskLog(PaasProcessNodeTaskEntityExt item, Map<String, UserEntity> userMap, ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = new ProcessNodeTaskLogPoJo();
        try {
            BeanUtil.copyProperties(item, processNodeTaskLogPoJo);
            // 会签或签描述字段
            processNodeTaskLogPoJo.setSignTypeDesc(SignTypeEnum.getSignTypeEnum(item.getSignType()));
            // 审批图片
            if (StringUtil.isNotEmpty(item.getImages())) {
                processNodeTaskLogPoJo.setImages(JsonHelperUtil.parseArray(item.getImages(), String.class));
            }
            // 审批附件
            if (StringUtil.isNotEmpty(item.getAttachment())) {
                List<String> attachmentStrList = JsonHelperUtil.parseArray(item.getAttachment(), String.class);
                List<PaasAttachmentEntityExt> attachmentList = new ArrayList<>();
                attachmentStrList.forEach((attachmentItem) -> {
                    PaasAttachmentEntityExt attachment = JSONObject.parseObject(attachmentItem, PaasAttachmentEntityExt.class);
                    attachmentList.add(attachment);
                });
                processNodeTaskLogPoJo.setAttachmentList(attachmentList);
            }
            // 开始节点描述
            if (item.getNodeType().equals(NodeTypeEnum.START_PROCESS_NODE.getNodeType())) {
                processNodeTaskLogPoJo.setStartNodeDesc(I18nMessageUtil.getMessage(PaasConstant.INITIATE_AN_APPLICATION));
                if (Objects.equals(item.getTaskType(), TaskTypeEnum.REVOKE.getType())) {
                    processNodeTaskLogPoJo.setStartNodeDesc(I18nMessageUtil.getMessage(PaasConstant.REVOKE_PROCESS));
                } else if (Objects.equals(item.getTaskType(), TaskTypeEnum.AGAIN_COMMIT.getType())) {
                    processNodeTaskLogPoJo.setStartNodeDesc(TaskTypeEnum.AGAIN_COMMIT.getStatusMemo());
                }
            } else {
                processNodeTaskLogPoJo.setStartNodeDesc("");
            }
            processNodeTaskLogPoJo.setOperatorUser(userMap.get(item.getUserId()));
            // 判断负责人是否为当前登录用户
            UserEntity userEntity = processNodeTaskLogPoJo.getOperatorUser();
            processNodeTaskLogPoJo.setTaskTypeDesc(TaskTypeEnum.getStatusMemo(item.getTaskType()));
            if (userEntity != null && processNodeTaskGetDTO.getUserId().equals(userEntity.getUserId())) {
                processNodeTaskLogPoJo.setIsMe(1);
                processNodeTaskLogPoJo.setIsMeDesc(I18nMessageUtil.getMessage(CommonConstant.ME));
                if (item.getTaskType().equals(TaskTypeEnum.UNTREATED.getType())) {
                    processNodeTaskLogPoJo.setTaskTypeDesc(I18nMessageUtil.getMessage(PaasConstant.WAITING_FOR_ME_TO_APPROVE));
                }
            } else {
                processNodeTaskLogPoJo.setIsMe(0);
                processNodeTaskLogPoJo.setIsMeDesc("");
                if(Objects.equals(PaasConstant.SYS_USER_ID, item.getUserId())) {
                    processNodeTaskLogPoJo.setIsMeDesc(I18nMessageUtil.getMessage(CommonConstant.SYSTEM));
                    processNodeTaskLogPoJo.setOpinion(I18nMessageUtil.getMessage(I18nStringConstant.CURRENT_NODE_APPROVER_EMPTY));
                    // 系统管理员
                    UserEntity systemUser = new UserEntity();
                    systemUser.setUserId(item.getUserId());
                    systemUser.setRoleIds("|1|2|3|23|");
                    systemUser.setCorpid(item.getCorpid());
                    systemUser.setAvatar("");
                    systemUser.setName(I18nMessageUtil.getMessage(CommonConstant.SYSTEM));
                    processNodeTaskLogPoJo.setOperatorUser(systemUser);
                }
            }
            // 转交人
            if (StringUtil.isNotEmpty(item.getTransferUserId())) {
                processNodeTaskLogPoJo.setTransferUser(userMap.get(item.getTransferUserId()));
            }
            // 撤回操作人
            if (StringUtil.isNotEmpty(item.getRevokeUserId())) {
                processNodeTaskLogPoJo.setRevokeUser(userMap.get(item.getRevokeUserId()));
            }
            // 回退人
            /*if (item.getBackspaceNode() != null && item.getBackspaceNode() != 0) {
                ProcessNodeTaskGetDTO result = new ProcessNodeTaskGetDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, result);
                Map<Long, PaasProcessTemplateNodeEntityExt> nodeMap = getNodeMap(processNodeTaskGetDTO);
                processNodeTaskLogPoJo.setBackNodeName(nodeMap.get(item.getBackspaceNode()).getName());
            }*/
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取流程日志对象出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskLogPoJo;
    }

    /*private Map<Long, PaasProcessTemplateNodeEntityExt> getNodeMap(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        Map<Long, PaasProcessTemplateNodeEntityExt> nodeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            Map<String, Object> params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
            List<PaasProcessTemplateNodeEntityExt> nodeList = processTemplateNodeModel.list(params);
            if (nodeList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }
            nodeList.forEach((nodeItem) -> {
                nodeMap.put(nodeItem.getId(), nodeItem);
            });
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取流程节点容器出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return nodeMap;
    }*/

    /**
     * 获取用户名称
     *
     * @param processNodeTaskGetDTO
     * @param paasProcessNodeTaskVO
     * @throws XbbException
     */
    private void getUserName(ProcessNodeTaskGetDTO processNodeTaskGetDTO, PaasProcessNodeTaskVO paasProcessNodeTaskVO) throws XbbException {
        try {
            UserGetDTO userGetDTO = new UserGetDTO();
            BeanUtil.copyProperties(processNodeTaskGetDTO, userGetDTO);
            List<String> userIdsList = new ArrayList<>();
            userIdsList.add(paasProcessNodeTaskVO.getCreatorId());
            userIdsList.add(paasProcessNodeTaskVO.getUserId());
            userIdsList.add(paasProcessNodeTaskVO.getTransferUserId());
            userGetDTO.setTargetUserId(userIdsList);
            UserGetVO userGetVO = userService.getUserInfoByTargetUserId(userGetDTO);
            if (userGetVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            List<UserVO> userList = userGetVO.getUserList();
            Map<String, UserVO> userVOMap = new HashMap<>(userList.size());
            userList.forEach((item) -> userVOMap.put(item.getUserId(), item));
            paasProcessNodeTaskVO.setCreatorUser(userVOMap.get(paasProcessNodeTaskVO.getCreatorId()));
            paasProcessNodeTaskVO.setOperatorUser(userVOMap.get(paasProcessNodeTaskVO.getUserId()));
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getTransferUserId())) {
                paasProcessNodeTaskVO.setTransferUser(userVOMap.get(paasProcessNodeTaskVO.getTransferUserId()));
            }
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getRevokeUserId())) {
                paasProcessNodeTaskVO.setRevokeUser(userVOMap.get(paasProcessNodeTaskVO.getRevokeUserId()));
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasProcessNodeTaskServiceImpl获取用户名称失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     *
     * @param processNodeTaskListDTO 节点任务dto
     * @param templateNodeMap        模板节点集合容器
     * @param processTaskMap         流程任务集合
     * @param nodeTaskList           节点任务集合
     * @return
     * @throws XbbException
     */
    private List<SummaryDataVO> getSummaryList(ProcessNodeTaskListDTO processNodeTaskListDTO,
                                               Map<Long, PaasProcessTemplateNodeEntityExt> templateNodeMap, Map<Long, PaasProcessTaskEntity> processTaskMap,
                                               List<PaasProcessNodeTaskEntityExt> nodeTaskList) throws XbbException {
        List<SummaryDataVO> summaryList = new ArrayList<>();
        String corpid = processNodeTaskListDTO.getCorpid();
        String processType = processNodeTaskListDTO.getProcessType();
        Set<Long> workOrderIdList = new HashSet<>();
        Set<Long> formIdList = new HashSet<>();
        Set<Long> taskIdList = new HashSet<>();
        for (Map.Entry<Long, PaasProcessTaskEntity> entry : processTaskMap.entrySet()) {
            PaasProcessTaskEntity item = entry.getValue();
            taskIdList.add(entry.getKey());
            if (Objects.equals(item.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                workOrderIdList.add(item.getFormId());
            } else {
                formIdList.add(item.getFormId());
            }
        }
        try {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("del", 0);
            params.put("idIn", workOrderIdList);
            // 表单列表 需要用到表单名称
            List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.findEntitys(params);
            params.put("idIn", formIdList);
            List<PaasFormEntityExt> formList = paasFormModel.list(params);
            params.remove("orderByStr");

            Map<String, PaasFormEntityExt> formMap = new HashMap<>(formList.size() + workOrderFormList.size());
            formList.forEach((item) -> formMap.put((item.getAppId() + "_" +item.getId()), item));
            workOrderFormList.forEach((item) -> {
                PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
                BeanUtil.copyProperties(item, paasFormEntityExt);
                formMap.put((paasFormEntityExt.getAppId() + "_" +paasFormEntityExt.getId()), paasFormEntityExt);
            });
            // 获取所有解释数据列表
            params.remove("idIn");
            params.remove(ParameterConstant.COLUMNS);
            params.put("formIdIn", formIdList);
            List<PaasFormExplainEntity> explainList = paasFormExplainModel.list(params);
            params.remove(ParameterConstant.COLUMNS);
            params.put("formIdIn", workOrderIdList);
            List<WorkOrderExplainEntity> workOrderExplainList = workOrderExplainModel.list(params);

            Map<String, PaasFormExplainEntity> explainMap = new HashMap<>(explainList.size() + workOrderExplainList.size());
            explainList.forEach((item) -> explainMap.put((item.getAppId() + "_" + item.getFormId()), item));
            workOrderExplainList.forEach((item) -> {
                PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
                BeanUtil.copyProperties(item, paasFormExplainEntity);
                explainMap.put((paasFormExplainEntity.getAppId() + "_" + paasFormExplainEntity.getFormId()), paasFormExplainEntity);
            });
            // 用户列表
            params.remove(ParameterConstant.COLUMNS);
            params.remove("formIdIn");
            params.remove("del");
            List<UserEntity> allUser = userModel.findEntitys(params);
            if (allUser == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }
            Map<String, UserEntity> userMap = new HashMap<>(allUser.size());
            allUser.forEach((item) -> userMap.put(item.getUserId(), item));
            // 部门列表
            params.remove(ParameterConstant.COLUMNS);
            List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
            if (departmentList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
            }
            Map<String, DepartmentEntity> departmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));
            // 获取所有任务数据列表
            params = BeanUtil.convertBean2Map(processNodeTaskListDTO, true);
            params.put("taskIdIn", taskIdList);
            // 有可能有脏数据，导致流程状态和数据状态不一致，导致NPE，故删除流程状态筛选
            params.remove("flowStatus");
            // 单据拆分兼容处理
            specialParams(params, processNodeTaskListDTO.getBusinessType());
            // 去掉saas_need_pojo 这个对象太大，没必要
            params.put(ParameterConstant.COLUMNS, "id,corpid,app_id,menu_id,form_id,form_data_id,template_id,task_id,flow_status,`data`,owner_id,department_id,serial_no,creator_id,add_time,update_time,del,saas_mark,business_type,sub_business_type");
            List<PaasProcessDataEntity> processDataList = paasProcessDataModel.list(params);
            if (processDataList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            Map<Long, PaasProcessDataEntity> processDataMap = new HashMap<>(processDataList.size());
            processDataList.forEach((item) -> processDataMap.put(item.getTaskId(), item));
            ProcessNodeTaskGetDTO processNodeTaskGetDTO = new ProcessNodeTaskGetDTO();
            BeanUtil.copyProperties(processNodeTaskListDTO, processNodeTaskGetDTO);
            // 待 *** 审批 首页用
            Map<Long, List<PaasProcessNodeTaskEntityExt>> nodeTaskMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue())) {
                params.clear();
                params.put("corpid", corpid);
                params.put("taskIdIn", taskIdList);
                params.put("taskType", TaskTypeEnum.UNTREATED.getType());
                params.put("del", 0);
                List<PaasProcessNodeTaskEntityExt> nodeTaskEntityExtList = paasProcessNodeTaskModel.findEntitys(params);
                nodeTaskEntityExtList.forEach(item -> {
                    List<PaasProcessNodeTaskEntityExt> extList = new ArrayList<>();
                    if (nodeTaskMap.containsKey(item.getTaskId())) {
                        extList.addAll(nodeTaskMap.get(item.getTaskId()));
                        extList.add(item);
                        nodeTaskMap.put(item.getTaskId(), extList);
                    } else {
                        extList.add(item);
                        nodeTaskMap.put(item.getTaskId(), extList);
                    }
                });
            }
            for (PaasProcessNodeTaskEntityExt nodeTask : nodeTaskList) {
                String key = nodeTask.getAppId() + "_" + nodeTask.getFormId();
                Long taskId = nodeTask.getTaskId();
                // 删除的菜单不需要处理
                PaasFormEntityExt paasFormEntityExt = formMap.get(key);
                if (paasFormEntityExt == null) {
                    continue;
                }
                if (!processDataMap.containsKey(taskId)) {
                    continue;
                }
                //22252 【审批】第一套测试环境（皇上），王碧云的账户 点击“抄送给我的审批”，弹出“服务器开小差”(新老数据问题)
                if (templateNodeMap.get(nodeTask.getTemplateNodeId())==null){
                    continue;
                }
                SummaryDataDTO summaryDataDTO = new SummaryDataDTO();
                BeanUtil.copyProperties(processNodeTaskListDTO, summaryDataDTO);
                summaryDataDTO.setTaskId(taskId);
                summaryDataDTO.setMenuId(nodeTask.getMenuId());
                summaryDataDTO.setCorpid(corpid);
                summaryDataDTO.setPaasProcessDataEntity(processDataMap.get(taskId));
                summaryDataDTO.setPaasFormExplainEntity(explainMap.get(key));
                summaryDataDTO.setSummaryEntityList(templateNodeMap.get(nodeTask.getTemplateNodeId()).getFieldPermissionList());
                summaryDataDTO.setUserId(processNodeTaskListDTO.getUserId());
                summaryDataDTO.setUserMap(userMap);
                summaryDataDTO.setDepartmentMap(departmentMap);
                summaryDataDTO.setPaasProcessTaskEntity(processTaskMap.get(taskId));
                SummaryDataVO summaryDataVO = paasProcessDataService.getSummaryAndTitle(summaryDataDTO);
                PaasProcessNodeTaskVO paasProcessNodeTaskVO = new PaasProcessNodeTaskVO();
                BeanUtil.copyProperties(nodeTask, paasProcessNodeTaskVO);
                PaasProcessTaskEntity paasProcessTaskEntity = processTaskMap.get(taskId);
                if (nodeTaskMap.containsKey(nodeTask.getTaskId())){
                    List<PaasProcessNodeTaskEntityExt> paasProcessNodeTaskEntityExts = nodeTaskMap.get(nodeTask.getTaskId());
                    for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : paasProcessNodeTaskEntityExts) {
                            paasProcessNodeTaskVO.setSignType(paasProcessNodeTaskEntityExt.getSignType());
                            break;
                    }
                }
                paasProcessNodeTaskVO.setSaasMark(paasProcessTaskEntity.getSaasMark());
                paasProcessNodeTaskVO.setBusinessType(paasProcessTaskEntity.getBusinessType() == null ? 0 : paasProcessTaskEntity.getBusinessType());
                paasProcessNodeTaskVO.setOpinionFlag(templateNodeMap.get(nodeTask.getTemplateNodeId()).getOpinionFlag());
                paasProcessNodeTaskVO.setCreatorId(paasProcessTaskEntity.getCreatorId());
                // 确定详情是在哪个列表（撤回只在我提交的列表显示）
                paasProcessNodeTaskVO.setProcessType(processType);
                getUserName(processNodeTaskGetDTO, paasProcessNodeTaskVO);
                paasProcessNodeTaskVO.setTaskTypeMemo(ProcessSearchStatusTodoEnum.getStatusMemo(paasProcessNodeTaskVO.getTaskType()));
                TaskTypeEnum typeEnum = TaskTypeEnum.getTaskTypeEnum(paasProcessNodeTaskVO.getTaskType());
                if (typeEnum != null) {
                    paasProcessNodeTaskVO.setColor(typeEnum.getColor());
                }
                UserVO creatorUser = paasProcessNodeTaskVO.getCreatorUser();
                if (Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())) {
                    paasFormEntityExt.setName(XbbRefTypeEnum.INVOICE.getName());
                }
                if (creatorUser == null) {
                    summaryDataVO.setTitle("***"+ I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));
                } else {
                    summaryDataVO.setTitle(creatorUser.getName() + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));
                }
                summaryDataVO.setProcessNodeTask(paasProcessNodeTaskVO);
                if (Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                    PaasProcessDataEntity processDataEntity = processDataMap.get(taskId);
                    JSONObject processData = JSONObject.parseObject(processDataEntity.getData());
                    List<SummaryDataPoJo> dataPoJos = summaryDataVO.getSummaryList();
                    for (SummaryDataPoJo summaryDataPoJo : dataPoJos) {
                        if (!Objects.equals(summaryDataPoJo.getAttr(), InstockEnum.REF_ID.getAttr())) {
                            continue;
                        }
                        Integer type = processData.getInteger(InstockEnum.TYPE.getAttr());
                        if (Objects.equals(InstockTypeEnum.OTHER_INSTOCK.getCode(), type)) {
                            summaryDataPoJo.setValue(Arrays.asList(I18nMessageUtil.getMessage(CommonConstant.NOTHING)));
                        }
                    }
                }
                summaryList.add(summaryDataVO);
                // 当前最新审批中的节点的负责人列表 首页用
                if (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue())) {
                    // 获取当前节点未审批的审批人 首页需要用到
                    List<PaasProcessNodeTaskEntityExt> taskEntityExt = nodeTaskMap.get(nodeTask.getTaskId());
                    List<UserEntity> userList = new ArrayList<>();
                    if (taskEntityExt != null) {
                        taskEntityExt.forEach(item -> {
                            if (userMap.containsKey(item.getUserId())) {
                                userList.add(userMap.get(item.getUserId()));
                            }
                        });
                    }
                    List<Object> userNameList = new ArrayList<>();
                    boolean isWeb = Objects.equals(processNodeTaskListDTO.getPlatform(), PlatFormEnum.WEB.getValue());
                    for (UserEntity user : userList) {
                        if (isWeb) {
                            userNameList.add(user.getName());
                        } else {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, user.getUserId());
                            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, user.getName());
                            userNameList.add(jsonObject);
                        }
                    }
                    summaryDataVO.setLatestApproveUserList(userNameList);
                }
                // 提交给我的审批按钮初始化
                /*if (Objects.equals(processType, ProcessTypeEnum.TODO.getValue())) {
                    summaryDataVO.setProcessOperatePermission(getProcessOperatorForIndex(templateNodeMap.get(nodeTask.getTemplateNodeId())));
                }*/
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask获取任务中摘要、任务、表单数据出错，", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return summaryList;
    }

    /**
     * 首页获取流程操作
     *
     * @param templateNode
     * @return
     * @throws XbbException
     */
    private ProcessTemplateNodeVO getProcessOperatorForIndex(PaasProcessTemplateNodeEntityExt templateNode) throws XbbException {
        List<ProcessOperateVo> resultList = new ArrayList<>();
        ProcessTemplateNodeVO processOperatePermission = new ProcessTemplateNodeVO();
        try {
            if (templateNode.getCommitFlag().equals(1)) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setText(templateNode.getCommitText());
                operatePoJo.setFlag(templateNode.getCommitFlag());
                operatePoJo.setType(TaskTypeEnum.COMMIT.getType());
                resultList.add(operatePoJo);
            }

            if (templateNode.getEndFlag().equals(1)) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setText(templateNode.getEndText());
                operatePoJo.setFlag(templateNode.getEndFlag());
                operatePoJo.setType(TaskTypeEnum.END.getType());
                resultList.add(operatePoJo);
            }
            processOperatePermission.setProcessOperate(resultList);
            return processOperatePermission;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库获取流程操作权限出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }


    private void getSaasBusinessType(ProcessNodeTaskListDTO processNodeTaskListDTO, Map<String, Object> param) {
        // SaaS业务处理
        if (Objects.equals(processNodeTaskListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // saas应用下也可能有paas的自定义表单 所以需要去掉saasMark
            processNodeTaskListDTO.setSaasMark(null);
            Integer saasAppType = processNodeTaskListDTO.getSaasAppType();
            param.remove("saasMark");
            if (Objects.equals(saasAppType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                param.put("businessType", XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                if (Objects.isNull(processNodeTaskListDTO.getBusinessType())) {
                    Long appId = processNodeTaskListDTO.getAppId();
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("corpid", processNodeTaskListDTO.getCorpid());
                    params.put("appId", appId);
                    params.put("del", 0);
                    List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.list(params);
                    if (paasFormEntityExts.size() > 0) {
                        List<Long> formIdList = new ArrayList<>();
                        paasFormEntityExts.forEach(item -> {
                            formIdList.add(item.getId());
                        });
                        param.put("formIdIn", formIdList);
                    }
                }
            }
        }
    }

    private boolean isEmptyList(ProcessNodeTaskListDTO processNodeTaskListDTO, ProcessNodeTaskListVO processNodeTaskListVO, List<PaasProcessTaskEntity> taskList) {
        if (taskList.isEmpty()) {
            processNodeTaskListVO.setList(new ArrayList<>());
            int page = processNodeTaskListDTO.getPage() == null ? 1 : processNodeTaskListDTO.getPage();
            int pageSize = processNodeTaskListDTO.getPageSize() == null ? 20 : processNodeTaskListDTO.getPageSize();
            processNodeTaskListVO.setPageHelper(new PageHelper(page, pageSize).setRowsCount(processNodeTaskListVO.getList().size()));
            return true;
        }
        return false;
    }

    private void setOwnIdAndCoUserId(JSONObject data, ValidateDataDTO validateDataDTO) {
        // 解析新版协同人和负责人
        JSONArray ownIdList = data.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
        JSONArray coUserIdList = data.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
        if (!Objects.isNull(ownIdList)) {
            List<ReturnUserAndDepartmentPojo> ownList = new ArrayList<>();
            for (Object userId : ownIdList) {
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                returnUserAndDepartmentPojo.setId(Objects.toString(userId, ""));
                ownList.add(returnUserAndDepartmentPojo);
            }
            validateDataDTO.setOwnerIds(ownList);
        }
        if (!Objects.isNull(coUserIdList)) {
            List<ReturnUserAndDepartmentPojo> coUserList = new ArrayList<>();
            for (Object userId : coUserIdList) {
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                returnUserAndDepartmentPojo.setId(Objects.toString(userId, ""));
                coUserList.add(returnUserAndDepartmentPojo);
            }
            validateDataDTO.setCoUserId(coUserList);
        }
    }

    /**
     * 设置特殊参数
     *
     * @param processNodeTaskUpdateDTO
     * @param validateDataDTO
     * @throws
     * @author long.rao
     * @date 2019-10-19 18:18
     */
    private void setSpecialParam(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO, ValidateDataDTO validateDataDTO) throws XbbException{
        if (Objects.equals(processNodeTaskUpdateDTO.getBusinessType(), XbbRefTypeEnum.QUOTATION.getCode())) {
            // 报价单组号不为1.0时，代表创建新版本(目前用于报价单新版本时不用校验同一组号的报价名称)
            JSONObject data = processNodeTaskUpdateDTO.getDataList();
            String version = FastJsonHelper.getStringOrDefaultFromFormData(data, QuotationEnum.VERSION.getAttr(), StringConstant.DEFAULT_VERSION);
            if (!Objects.equals(version, StringConstant.DEFAULT_VERSION)) {
                validateDataDTO.setNewVersion(BasicConstant.ONE);
            }
        }
    }

    private void saasSpecialHandle(PaasProcessNodeTaskVO paasProcessNodeTaskVO, JSONObject dataJsonObject, ProcessNodeTaskGetVO processNodeTaskGetVO, Integer businessType) throws XbbException {
        if (Objects.equals(businessType, XbbRefTypeEnum.QUOTATION.getCode())) {
            String version = FastJsonHelper.getStringOrDefaultFromFormData(dataJsonObject, QuotationEnum.VERSION.getAttr(), StringConstant.DEFAULT_VERSION);
            String groupNumber = FastJsonHelper.getStringOrDefaultFromFormData(dataJsonObject, QuotationEnum.GROUP_NUMBER.getAttr(), "");
            if (!Objects.equals(version, StringConstant.DEFAULT_VERSION)) {
                // 如果报价单版本号不是1.0，那么他就是创建新版本,新版本名称判重有些特殊（组号相同的不盘虫）
                JSONObject newVersionObj = new JSONObject();
                newVersionObj.put("newVersion", BasicConstant.ONE);
                newVersionObj.put(QuotationEnum.GROUP_NUMBER.getSaasAttr(), groupNumber);
                List<FieldAttrEntity> headList = processNodeTaskGetVO.getHeadList();
                headList.forEach(item -> {
                    if (Objects.equals(item.getAttr(), QuotationEnum.NAME.getAttr())) {
                        item.setQuotationNameRepeat(newVersionObj);
                    }
                });
                paasProcessNodeTaskVO.setQuotationNameRepeat(newVersionObj);
            }
        }
    }

    /**
     * @Description: 单据拆分后 审批筛选老数据兼容
     * @Param: [param, businessType]
     * @return: void
     * @Author: cyy
     * @Date: 2019/12/6
     */
    private void specialParams(Map<String, Object> param, Integer businessType) {
        List<Integer> typeEnumInteger = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (StockConstant.INSTOCK_TYPE_LIST.contains(businessType)) {
            typeEnumInteger = InstockTypeEnum.getInstockTypeEnumsByStockBusinessType(businessType);
            param.put("stockTypeIn",typeEnumInteger);
        }
        if (StockConstant.OUTSTOCK_TYPE_LIST.contains(businessType)){
            typeEnumInteger = OutstockTypeEnum.getOutstockTypeEnumsByStockBusinessType(businessType);
            param.put("stockTypeIn",typeEnumInteger);
        }
        if (StockConstant.EXCLUDE_INSTOCK_TYPE_LIST.contains(businessType)){
            typeEnumInteger = InstockTypeEnum.getInstockTypeEnumsByStockBusinessType(businessType);
            param.put("stockTypeIn",typeEnumInteger);

            List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.OTHER_INSTOCK.getCode(),businessType);
            param.put("businessTypeIn",businessTypeIn);
            param.remove("businessType");
        }
        if (StockConstant.EXCLUDE_OUTSTOCK_TYPE_LIST.contains(businessType)){
            typeEnumInteger = OutstockTypeEnum.getOutstockTypeEnumsByStockBusinessType(businessType);
            param.put("stockTypeIn",typeEnumInteger);

            List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),businessType);
            param.put("businessTypeIn",businessTypeIn);
            param.remove("businessType");
        }
    }

	@Override
	public PaasBatchPrintByProcessVO getBatchPrintByProcess(PaasBatchPrintByProcessDTO paasBatchPrintByProcessDTO) throws XbbException {
        PaasBatchPrintByProcessVO paasBatchPrintByProcessVO = new PaasBatchPrintByProcessVO();
        // 设置appId,menuId等值
        BeanUtil.copyProperties(paasBatchPrintByProcessDTO, paasBatchPrintByProcessVO);
        // 打印权限
        boolean printFlag;
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), paasBatchPrintByProcessDTO.getSaasMark())) {
            printFlag = hasPrintPermission(paasBatchPrintByProcessDTO.getBusinessType(), paasBatchPrintByProcessDTO.getLoginUser().getPermSet());
        } else {
            UserFormPermissionVO userFormPermissionVO = userService.getUserFormPermissionInternal(paasBatchPrintByProcessDTO.getCorpid(),
                    paasBatchPrintByProcessDTO.getUserId(), paasBatchPrintByProcessDTO.getAppId(), paasBatchPrintByProcessDTO.getMenuId());
            PermissionTermsPojo permissionTerms = userFormPermissionVO.getFormPermission().getPermission();
            printFlag = Objects.equals(BasicConstant.ONE, permissionTerms.getPrint()) || paasBatchPrintByProcessDTO.getLoginUser().isAdminOrBoss();
        }
        if(!printFlag) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), "“" + paasBatchPrintByProcessDTO.getFormName() + "”表单打印"));
        }

        // 获取数据
        ProcessNodeTaskListVO processNodeTaskListVO = new ProcessNodeTaskListVO();
        ProcessNodeTaskListDTO processNodeTaskListDTO = new ProcessNodeTaskListDTO();
        BeanUtil.copyProperties(paasBatchPrintByProcessDTO, processNodeTaskListDTO);
        ProcessTypeEnum processTypeEnum = ProcessTypeEnum.getByValue(paasBatchPrintByProcessDTO.getProcessType());
        if (Objects.isNull(processTypeEnum)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, "审批类型不正确");
        }
        switch (processTypeEnum) {
            case TODO:
                processNodeTaskListDTO.setNodeType(NodeTypeEnum.PROCESS_NODE.getNodeType());
                processNodeTaskListVO = todoList(processNodeTaskListDTO);
                break;
            case CREATE:
                processNodeTaskListDTO.setCreatorId(processNodeTaskListDTO.getUserId());
                processNodeTaskListDTO.setNodeType(NodeTypeEnum.START_PROCESS_NODE.getNodeType());
                processNodeTaskListVO = createList(processNodeTaskListDTO);
                break;
            case CC:
                processNodeTaskListDTO.setTaskType(TaskTypeEnum.CC.getType());
                processNodeTaskListVO = ccList(processNodeTaskListDTO);
                break;
            case ALL:
                processNodeTaskListVO = allList(processNodeTaskListDTO);
                break;
            default:
                break;
        }

        List<SummaryDataVO> list = processNodeTaskListVO.getList();
        if (Objects.isNull(list) || list.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100051, "您筛选的数据为空，无法打印！");
        }
        List<Object> resultList = new ArrayList<>();
        for (SummaryDataVO summaryDataVO : list) {
            PaasProcessNodeTaskVO processNodeTask = summaryDataVO.getProcessNodeTask();
            JSONObject object = new JSONObject();
            object.put("processTaskId", processNodeTask.getTaskId());
            object.put("processNodeTaskId", processNodeTask.getId());

            resultList.add(object);
        }
        paasBatchPrintByProcessVO.setList(resultList);

		return paasBatchPrintByProcessVO;
	}

    @Override
    public BaseVO readAllCcList(ProcessNodeAllReadDTO processNodeAllReadDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        String corpid = processNodeAllReadDTO.getCorpid();
        String userId = processNodeAllReadDTO.getUserId();
        Integer nodeType = processNodeAllReadDTO.getNodeType();
        HashMap<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("userId", userId);
        if (Objects.equals(nodeType,BasicConstant.THREE)) {
            param.put("taskType", TaskTypeEnum.CC.getType());
        }else if (Objects.equals(nodeType,BasicConstant.TWO)){
            param.put("taskType", TaskTypeEnum.COMMIT.getType());
            param.put("nodeType",NodeTypeEnum.START_PROCESS_NODE.getNodeType() );
        }else {
            // 防止出现其他的问题,目前只有我提交的和抄送的,其他一律不作更新操作
            return baseVO;
        }
        param.put("isNoRead",BasicConstant.ONE);
        param.put("del", 0);
        try {
            paasProcessNodeTaskModel.readAllCcList(param);
        } catch (Exception e) {
            throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100001,SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return baseVO;
    }

    @Override
    public ProcessNodeTaskGet4IndexVO detail4Index(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskGet4IndexVO processNodeTaskGet4IndexVO = new ProcessNodeTaskGet4IndexVO();
        // 获取用户部门容器
        Map<String, Object> params = BeanUtil.convertBean2Map(processNodeTaskGetDTO, true);
        params.remove("del");
        params.put(ParameterConstant.LEAVE_MARKS, BasicConstant.ONE);
        List<UserEntity> userList = userModel.findEntitys(params);
        params.remove(ParameterConstant.LEAVE_MARKS);
        if (userList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
        }
        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> {
            if (Objects.equals(item.getDel(), 1)) {
                item.setName(item.getName() + "(" + I18nMessageUtil.getMessage(I18nStringConstant.RESIGNED)+ ")");
            }
            userMap.put(item.getUserId(), item);
        });

        processNodeTaskGetDTO.setUserMap(userMap);
        if (Objects.equals(processNodeTaskGetDTO.getNeedOperate(),BasicConstant.ONE)){
            getOperations(processNodeTaskGetDTO,processNodeTaskGet4IndexVO);
        }
        if (Objects.equals(processNodeTaskGetDTO.getNeedRecords(),BasicConstant.ONE)){
            getLogs(processNodeTaskGetDTO,processNodeTaskGet4IndexVO);
        }
        return processNodeTaskGet4IndexVO;
    }

    /**
     * 获取下一个节点的信息
     *
     * @param taskGetDto 当前节点的信息
     * @return 下一个节点的信息
     * @throws XbbException 异常
     */
    @Override
    public ProcessNextNodeTaskGetVO nextNode(ProcessNodeTaskGetDTO taskGetDto) throws XbbException {
        taskGetDto.setProcessNodeTaskId(null);
        taskGetDto.setProcessTaskId(null);
        ProcessNodeTaskListDTO taskListDto = new ProcessNodeTaskListDTO();
        taskListDto.setCorpid(taskGetDto.getCorpid());
        taskListDto.setUserId(taskGetDto.getUserId());
        taskListDto.setLoginUser(taskGetDto.getLoginUser());
        taskListDto.setProcessType(ProcessTypeEnum.TODO.getValue());
        taskListDto.setNodeType(NodeTypeEnum.PROCESS_NODE.getNodeType());
        taskListDto.setTaskType(TaskTypeEnum.UNTREATED.getType());
        taskListDto.setPage(BasicConstant.ONE);
        taskListDto.setPageSize(BasicConstant.ONE);
        taskListDto.setCommitTime(new ArrayList<>());
        taskListDto.setCommitUserId("");
        ProcessNodeTaskListVO listVO  = this.todoList(taskListDto);
        if (Objects.isNull(listVO) || CollectionsUtil.isEmpty(listVO.getList())) {
            ProcessNextNodeTaskGetVO taskGetVO = new ProcessNextNodeTaskGetVO();
            taskGetVO.setExistNext(BasicConstant.ZERO);
            return taskGetVO;
        }
        SummaryDataVO summaryDataVO = listVO.getList().get(0);
        PaasProcessNodeTaskVO nodeTask = summaryDataVO.getProcessNodeTask();
        BeanUtil.copyProperties(nodeTask, taskGetDto);
        taskGetDto.setProcessNodeTaskId(nodeTask.getId());
        taskGetDto.setProcessTaskId(nodeTask.getTaskId());
        ProcessNodeTaskGetVO detail = this.detail(taskGetDto);
        ProcessNextNodeTaskGetVO getVO = new ProcessNextNodeTaskGetVO();
        BeanUtil.copyProperties(detail, getVO);
        getVO.setExistNext(BasicConstant.ONE);
        return getVO;
    }

    /**
	 * 获取详情页的打印权限
	 *
	 * @param businessType 业务类型
     * @param permSet 权限set
	 * @throws
	 * @return
	 * @author hongxiao
	 * @date 2020-03-30 15:31
	 * @since v4.16.0
	 * @version 4.16.0
	 */
    private boolean hasPrintPermission(Integer businessType, Set<String> permSet) {
        List<BusinessDetailButtonEnum> buttonEnumList = BusinessDetailButtonEnum.getByBusinessTypeAndPermission(businessType, permSet);

        for (BusinessDetailButtonEnum buttonEnum : buttonEnumList) {
            if (Objects.equals(SaasButtonEnum.PRINT.getAttr(), buttonEnum.getAnEnum().getAttr())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 增加节点名称返回
     * @param logList 历史日志和当前审批
     * @param paasProcessTemplateNodeEntityExtMap 查询结果
     */
    private void addTemplateNodeName(List<Object> logList, Map<Long, PaasProcessTemplateNodeEntityExt> paasProcessTemplateNodeEntityExtMap) {
        for (Object log : logList) {
            ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) log;
            // 判断是否是未审批
            if (TaskTypeEnum.UNTREATED.getType().equals(processNodeTaskLogPoJo.getTaskType())) {
                // 未审批从UnCommitNodeTaskList只拿第一个id
                List<ProcessNodeTaskLogPoJo> unCommitNodeTaskList = processNodeTaskLogPoJo.getUnCommitNodeTaskList();
                Long unCommiteTemplateNodeId = unCommitNodeTaskList.get(0).getTemplateNodeId();
                if (paasProcessTemplateNodeEntityExtMap.containsKey(unCommiteTemplateNodeId)) {
                    processNodeTaskLogPoJo.setTemplateNodeName(paasProcessTemplateNodeEntityExtMap.get(unCommiteTemplateNodeId).getName());
                    // 当下面这种情况时，前端渲染数据从unCommitNodeTaskList中获取，所以要往这里多放一个节点名
                    if (NodeTypeEnum.PROCESS_NODE.getNodeType().equals(processNodeTaskLogPoJo.getNodeType()) && Objects.equals(unCommitNodeTaskList.size(), 1)) {
                        unCommitNodeTaskList.get(0).setTemplateNodeName(paasProcessTemplateNodeEntityExtMap.get(unCommiteTemplateNodeId).getName());
                    }
                }
            } else if (paasProcessTemplateNodeEntityExtMap.containsKey(processNodeTaskLogPoJo.getTemplateNodeId())) {
                processNodeTaskLogPoJo.setTemplateNodeName(paasProcessTemplateNodeEntityExtMap.get(processNodeTaskLogPoJo.getTemplateNodeId()).getName());
            }
        }
    }
}
